Einführung in WebSocket und TypeScript für Echtzeitanwendungen
Moderne Webanwendungen erfordern zunehmend einen sofortigen Datenaustausch zwischen Client und Server. Das traditionelle HTTP-Protokoll, das nach dem „Anfrage-Antwort"-Prinzip funktioniert, ist für Aufgaben, bei denen die Geschwindigkeit der Informationsübermittlung entscheidend ist, nicht geeignet: Online-Chats, Börsenkurse, Mehrspieler-Spiele oder Überwachungssysteme. Hier kommt WebSocket ins Spiel – ein Protokoll, das eine dauerhafte bidirektionale Verbindung ermöglicht.
In Kombination mit TypeScript – einer streng typisierten Obermenge von JavaScript – wird die Entwicklung von WebSocket-Anwendungen nicht nur effizient, sondern auch sicher. TypeScript ermöglicht es, Fehler bereits zur Kompilierungszeit zu erkennen, verbessert die Lesbarkeit des Codes und vereinfacht die Refaktorisierung. In diesem Artikel werden wir den gesamten Zyklus der Erstellung einer Echtzeitanwendung mit WebSocket und TypeScript durchgehen: von der Theorie bis zu praktischen Beispielen.
Grundlagen von WebSocket: Wie das Protokoll funktioniert
Was ist WebSocket?
WebSocket (RFC 6455) ist ein Protokoll, das eine dauerhafte Verbindung zwischen einem Client (Browser) und einem Server herstellt. Nach dem Handshake können Daten in beide Richtungen ohne erneute HTTP-Anfragen übertragen werden. Dies reduziert Latenzzeiten und Netzwerklast.
Unterschied zu HTTP
- HTTP: Der Client initiiert eine Anfrage → der Server antwortet → die Verbindung wird geschlossen (oder bleibt für folgende Anfragen offen, wird aber weiterhin vom Client initiiert).
- WebSocket: Nach dem Verbindungsaufbau kann der Server jederzeit Daten an den Client senden (Push-Benachrichtigungen).
Lebenszyklus einer WebSocket-Verbindung
- Handshake: Der Client sendet eine HTTP-Anfrage mit dem Header
Upgrade: websocket. Der Server antwortet mit dem Code 101 Switching Protocols. - Datenaustausch: Nach erfolgreichem Handshake wechselt die Verbindung zum WebSocket-Protokoll. Daten werden in Form von Frames übertragen.
- Schließen: Jede Seite kann das Schließen der Verbindung initiieren, indem sie einen speziellen Steuerungs-Frame sendet.
Erstellen eines WebSocket-Servers mit TypeScript
Bibliotheksauswahl
Für die Serverseite verwenden wir die beliebte Bibliothek ws – eine leichte und schnelle Implementierung von WebSocket für Node.js. Installieren wir sie zusammen mit den Typen für TypeScript:
npm install wsnpm install -D @types/wsBasis-Server
Erstellen wir eine Datei server.ts:
import { WebSocketServer, WebSocket } from 'ws';
const PORT = 8080;const wss = new WebSocketServer({ port: PORT });
console.log(`WebSocket-Server gestartet auf ws://localhost:${PORT}`);
wss.on('connection', (ws: WebSocket) => { console.log('Neue Verbindung');
// Sende eine Willkommensnachricht ws.send('Willkommen auf dem Server!');
// Verarbeitung eingehender Nachrichten ws.on('message', (message: Buffer) => { const text = message.toString(); console.log(`Empfangen: ${text}`);
// Echo-Antwort ws.send(`Echo: ${text}`); });
// Verarbeitung der Verbindungsschließung ws.on('close', () => { console.log('Client hat die Verbindung getrennt'); });
// Fehlerbehandlung ws.on('error', (error: Error) => { console.error('WebSocket-Fehler:', error); });});Verarbeitung verschiedener Nachrichtentypen
In realen Anwendungen sind Nachrichten oft im JSON-Format strukturiert. Erstellen wir einen typisierten Handler:
interface ChatMessage { type: 'message' | 'join' | 'leave'; username: string; content?: string; timestamp: number;}
wss.on('connection', (ws: WebSocket) => { ws.on('message', (data: Buffer) => { try { const msg: ChatMessage = JSON.parse(data.toString()); switch (msg.type) { case 'join': console.log(`${msg.username} ist beigetreten`);