WebSocket Protokoll

6 Kernkonzepte
Die wichtigsten WebSocket-Konzepte für Echtzeit-Kommunikation: ws / wss · Handshake · Framing · Message Types · Ping/Pong · Subprotocols WebSocket ermöglicht bidirektionale, persistente Verbindungen zwischen Client und Server – ideal für Echtzeit-Anwendungen wie Chats, Gaming, Live-Ticker und IoT.

Handshake – Verbindungsaufbau

HTTP Upgrade · Sec-WebSocket-Key · Sec-WebSocket-Accept
GET /chat HTTP/1.1 Host: example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13

WebSocket Handshake ist ein HTTP-basierter Upgrade-Prozess, der eine persistente Verbindung aufbaut. Der Client sendet einen Upgrade-Request, der Server bestätigt mit Status 101 Switching Protocols.

Wichtige Handshake-Header

Header Beschreibung
Upgrade: websocket Fordert Protokollwechsel an
Connection: Upgrade Bestätigt den Upgrade
Sec-WebSocket-Key Base64-codierter Zufallswert (16 Byte)
Sec-WebSocket-Version WebSocket-Protokollversion (13 = RFC 6455)
Sec-WebSocket-Protocol Gewünschtes Subprotokoll (z.B. chat, json, soap)
Sec-WebSocket-Extensions Erweiterungen (z.B. permessage-deflate)
Beispiele
# Client → Server (Handshake Request)
GET /ws HTTP/1.1
Host: chat.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Sec-WebSocket-Protocol: json
# Server → Client (Handshake Response)
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: json
Tipp: Der Sec-WebSocket-Accept wird aus dem Sec-WebSocket-Key berechnet (Key + UUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" → SHA-1 → Base64). Dies dient als einfache Authentifizierung des Handshakes.

Framing – Datenrahmen-Struktur

FIN · Opcode · Mask · Payload Length · Masking Key · Payload Data
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) | |N|V|V|V| |S| | | +-+-+-+-+-------+-+-------------+-------------------------------+

WebSocket Framing definiert die Struktur jedes Datenpakets. Jeder Frame enthält Steuerinformationen wie Opcode, Länge und optional einen Maskierungs-Key.

Frame-Komponenten

Feld Bits Beschreibung
FIN 1 Letzter Frame einer Nachricht (1 = letzter)
RSV1-3 3 Reserviert für Erweiterungen (0, wenn nicht genutzt)
Opcode 4 Typ des Frames (0x0-0xF)
Mask 1 Maskierung aktiv (Client → Server immer 1)
Payload Length 7/16/64 Länge der Nutzdaten (7 Bit, 16 Bit oder 64 Bit)
Masking Key 32 Maskierungsschlüssel (nur wenn Mask = 1)
Payload Data var Die eigentlichen Daten (nutzlast)
Tipp: Die Maskierung (Client → Server) ist ein Sicherheitsmechanismus gegen Cache-Poisoning-Angriffe. Server → Client Frames sind nicht maskiert. Die Payload-Länge wird wie folgt codiert: 0-125 = 7 Bit, 126 = 16 Bit, 127 = 64 Bit.

Message Types – Opcodes für Frames

0x1 Text · 0x2 Binary · 0x8 Close · 0x9 Ping · 0xA Pong
# Daten-Frames 0x1 Text (UTF-8) 0x2 Binary (beliebige Daten) # Steuer-Frames 0x8 Close Connection 0x9 Ping (Keep-Alive) 0xA Pong (Ping-Antwort)

Opcode definiert den Typ eines Frames. Daten-Frames übertragen Nutzdaten, Steuer-Frames verwalten die Verbindung (Ping/Pong, Close).

Alle Opcodes

Opcode Typ Beschreibung
0x0 Continuation Fortsetzungsframe (mehrere Frames für eine Nachricht)
0x1 Text UTF-8 Text-Nachricht
0x2 Binary Binäre Daten
0x3-0x7 Reserviert Für zukünftige Daten-Frames
0x8 Close Verbindung schließen (mit Statuscode)
0x9 Ping Keep-Alive (Client/Server kann Ping senden)
0xA Pong Antwort auf Ping
0xB-0xF Reserviert Für zukünftige Steuer-Frames
Beispiele
# Text-Nachricht (JSON)
Opcode: 0x1 (Text)
Payload: {"type":"chat","message":"Hallo Welt"}
# Binary-Nachricht (z.B. Bild)
Opcode: 0x2 (Binary)
Payload: <binäre Daten>
# Ping (Keep-Alive)
Opcode: 0x9 (Ping)
Payload: (optional, wird in Pong zurückgesendet)
# Close (Verbindung beenden)
Opcode: 0x8 (Close)
Payload: 0x03E8 (1000 - Normal Closure)
Tipp: Bei großen Nachrichten können Sie diese in mehrere Frames aufteilen (FIN=0). Der erste Frame hat den Opcode des Typs (z.B. 0x1 Text), alle folgenden Frames haben Opcode 0x0 (Continuation). Der letzte Frame hat FIN=1.

Close Codes & Control Frames – Verbindungsmanagement

1000 · 1001 · 1006 · 1011 · Ping/Pong
# Close Frame Payload (2 Bytes Statuscode + optionaler Grund) 0x03E8 (1000) Normal Closure 0x03EA (1002) Protocol Error 0x03F3 (1011) Internal Server Error

Control Frames (Ping, Pong, Close) verwalten die Verbindung. Close Codes geben den Grund für das Schließen der Verbindung an.

Wichtige Close Codes (RFC 6455)

Code Name Beschreibung
1000 Normal Closure Normales Schließen (kein Fehler)
1001 Going Away Server/Client geht offline
1002 Protocol Error Protokollfehler
1003 Unsupported Data Daten-Typ nicht unterstützt
1005 No Status Received Kein Statuscode empfangen (intern)
1006 Abnormal Closure Abnormales Schließen (Verbindung abgebrochen)
1007 Invalid Frame Payload Data Ungültige Nutzdaten
1008 Policy Violation Verstoß gegen Richtlinien
1009 Message Too Big Nachricht zu groß
1010 Mandatory Extension Erweiterung erforderlich
1011 Internal Server Error Interner Serverfehler
1012 Service Restart Server wird neu gestartet
1013 Try Again Later Service temporär nicht verfügbar
Beispiele
# Normal Closure (1000)
Close Frame Opcode: 0x8
Payload: 0x03E8 (Normal Closure)
# Protocol Error (1002)
Close Frame Opcode: 0x8
Payload: 0x03EA (Protocol Error)
# Ping/Pong (Keep-Alive)
Client → Server: Ping (0x9) mit Payload "ping-123"
Server → Client: Pong (0xA) mit gleicher Payload "ping-123"
Tipp: Ping/Pong wird automatisch von vielen WebSocket-Bibliotheken behandelt. Sie können Ping-Frames verwenden, um die Verbindung aktiv zu halten und Timeouts zu vermeiden. Die Payload von Ping wird in Pong zurückgesendet.

Subprotocols & Extensions – Anwendungsspezifische Protokolle

Sec-WebSocket-Protocol · permessage-deflate
Sec-WebSocket-Protocol: chat, json, soap Sec-WebSocket-Extensions: permessage-deflate # Server antwortet mit gewähltem Subprotokoll Sec-WebSocket-Protocol: json

Subprotocols definieren anwendungsspezifische Protokolle über WebSocket (z.B. JSON-RPC, SOAP, MQTT). Extensions erweitern die WebSocket-Funktionalität (z.B. Komprimierung).

Häufige Subprotocols

Subprotokoll Beschreibung
json JSON-basierte Nachrichten (häufig für APIs)
soap SOAP-Protokoll über WebSocket
graphql-ws GraphQL über WebSocket (Subscriptions)
mqtt MQTT über WebSocket (IoT)
xmpp XMPP (Chat) über WebSocket
stomp STOMP (Messaging) über WebSocket

Häufige Extensions

Extension Beschreibung
permessage-deflate Komprimierung der Nachrichten (RFC 7692)
permessage-deflate; server_no_context_takeover Kein Kontext-Übernahme (für bessere Komprimierung)
Beispiele
# Handshake mit Subprotokoll JSON
GET /api HTTP/1.1
Upgrade: websocket
Sec-WebSocket-Protocol: json, graphql-ws
# Server wählt JSON
HTTP/1.1 101 Switching Protocols
Sec-WebSocket-Protocol: json
# Verwendung von permessage-deflate (Komprimierung)
Sec-WebSocket-Extensions: permessage-deflate
# GraphQL Subscriptions über WebSocket
# Nach Subprotokoll graphql-ws:
# ConnectionInit → ConnectionAck → Subscribe → Next → Complete
Tipp: Subprotocols sind optional, aber empfohlen für strukturierte Kommunikation. Der Server sollte aus der Liste des Clients das passende Protokoll auswählen. Bei Verwendung von GraphQL Subscriptions ist graphql-ws der Standard.

Sicherheit & Best Practices – wss, Origin Check, Autorisierung

wss · Origin · Token · Rate Limiting
# Sichere Verbindung (wss://) wss://example.com/ws # Origin-Prüfung (Server) Origin: https://example.com # Autorisierung mit Token (Handshake) GET /ws?token=xyz

Sicherheitsmaßnahmen schützen WebSocket-Verbindungen vor Angriffen – durch Verschlüsselung, Origin-Prüfung, Authentifizierung und Ratenbegrenzung.

Best Practices

Maßnahme Beschreibung
wss:// (WSS) Immer WSS (WebSocket Secure) über TLS verwenden – wie HTTPS
Origin-Check Server prüft den Origin-Header auf erlaubte Domains
Authentifizierung Token über Query-Parameter oder Subprotokolle
Rate Limiting Begrenzung der Nachrichten pro Zeiteinheit pro Client
Message Size Limit Maximale Nachrichtengröße festlegen
Ping/Pong Timeout Regelmäßige Ping/Pong für Verbindungsüberwachung
Input Validation Alle eingehenden Nachrichten validieren
Close Handling Richtige Behandlung von Close-Frames (1000, 1001, etc.)
Beispiele
# WSS Verbindung (Browser)
const socket = new WebSocket("wss://api.example.com/ws");
# Token im Handshake (Query-Parameter)
const socket = new WebSocket(`wss://api.example.com/ws?token=${jwtToken}`);
# Origin-Prüfung (Server-seitig, Node.js ws)
const wss = new WebSocketServer({ port: 8080, verifyClient: function(info) {
const origin = info.origin || info.req.headers.origin;
return ["https://example.com", "https://app.example.com"].includes(origin);
} });
# Rate Limiting (Limit-Library)
const limiter = new RateLimiter({ points: 10, duration: 10 }); # 10 Nachrichten pro 10 Sekunden
Tipp: Verwenden Sie immer wss:// in Produktionsumgebungen. Authentifizieren Sie Clients beim Handshake (z.B. via Token im Query-Parameter) – das ist sicherer als nachträgliche Authentifizierung. Prüfen Sie den Origin-Header, um Cross-Origin-Angriffe zu verhindern.

WebSocket Protokoll im Überblick

ws/wss Protokoll-URL
ws:// (unverschlüsselt), wss:// (TLS)
101 Switching Protocols
Statuscode für Handshake
Opcode Frame-Typ
0x1 Text, 0x2 Binary, 0x8 Close
Ping/Pong Keep-Alive
0x9 Ping, 0xA Pong
Close Verbindung beenden
1000 (Normal), 1006 (Abnormal)
Mask Maskierung (Client → Server)
Sicherheitsmechanismus

Quick Summary

101
Handshake
Framing
Datenrahmen
0x1
Text
0x8
Close
Subprotocol
Anwendungsprotokoll
wss
Sicherheit
ws://example.com/ws · wss://example.com/ws · Upgrade: websocket