Begriff
WebSocket
Warum wichtig?
Dieser Begriff ist ein Knoten im SengakujiWorks-Wissensnetz. Nutze Level 0 für die erste Einordnung, Level 1 für Praxis, Level 2 für technische Struktur und Level 3 für Grenzen, Fallstricke und Expertenkontext.
HTTP ist höflich, aber distanziert. Client: "Gib mir Seite X." -> Server: "Hier." -> Auflegen. Wenn du chatten willst, ist das blöd ("Gibt es neue Nachrichten?" "Nein." "Jetzt?" "Nein."). WebSocket ist eine Dauerleitung. Nach dem Handschlag bleiben beide am Hörer. Server kann jederzeit senden: "Neue Nachricht!". Client kann jederzeit senden. Für Multiplayer-Games, Aktien-Ticker und Chat.
Merksatz: Ein Kommunikationsprotokoll auf Basis von TCP, das eine bidirektionale, dauerhafte Verbindung (Full Duplex) zwischen Client und Server über einen einzigen Socket ermöglicht.
JS Client:
const ws = new WebSocket('wss://chat.com/socket');
ws.onopen = () => ws.send('Hallo');
ws.onmessage = (event) => console.log(event.data);
Netzwerk-Tab im Browser: Status 101 Switching Protocols.
1. Upgrade Handshake
WebSocket startet als normales HTTP (GET /chat).
Header:
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Der Server antwortet 101 Switching Protocols.
Ab diesem Moment ist es kein HTTP mehr, sondern rohes TCP Stream.
Load Balancer (Nginx) müssen das verstehen (proxy_set_header Upgrade $http_upgrade;), sonst killen sie die Verbindung.
2. Keep-Alive (Ping/Pong)
NAT-Router und Firewalls hassen offene Verbindungen, auf denen nichts passiert. Nach 60 Sekunden Inaktivität kappen sie das Kabel ("Silent Drop"). Das Protokoll hat Ping/Pong Frames eingebaut. Der Server (oder Client) sendet regelmäßig "Ping". Gegenseite muss "Pong" antworten. Das hält den Tunnel offen.
3. Scaling (Sticky Sessions)
Skalierung ist die Hölle. Bei HTTP ist es egal, welcher Server antwortet (Stateless). Bei WebSocket bin ich fest mit Server 1 verbunden. Wenn ich eine Nachricht an "Gruppe A" sende, aber User 2 aus der Gruppe ist an Server 3 verbunden... sieht er sie nicht! Lösung: Pub/Sub Broker (Redis). Server 1 bekommt Nachricht -> Pusht in Redis -> Redis pusht an alle Server -> Server 3 sendet an User 2. Ohne Redis funktioniert WebSocket-Scaling nicht.
Das Reverse-Proxy Timeout Dilemma
Der häufigste Fehler beim Setup von WebSockets: Verbindungsabbrüche nach exakt 60 Sekunden.
HTTP Reverse-Proxies (wie Nginx, HAProxy oder AWS ALBs) wachen über Idle-Zeiträume. Wenn ein WebSocket-Client seinem Server 60 Sekunden lang keine Chat-Nachricht schreibt, sieht der Loadbalancer schlichtweg einen "toten" TCP-Stream und feuert unbarmherzig ein RST (Reset) – Ping weg!
Um das zu stoppen, müssen Pings (Heartbeats) zwingend konfiguriert werden. Man erhöht in Nginx zudem das proxy_read_timeout (oft von 60s auf 1h), und man implementiert App-Level Pings. Der Server schickt alle 30 Sekunden einen "Ping"-Frame, den der Browser unsichtbar mit "Pong" quitiert, nur damit alle firewalls und Proxies auf der Route "Aktivität" wahrnehmen.
Head-of-Line Blocking in WebSockets
WebSocket ist eine gewaltige Errungenschaft, operiert aber auf pures, altes TCP (Layer 4). Da in TCP die Paketzustellung zwingend sequenziell und garantiert ist, leidet WebSocket massiv unter Head-of-Line Blocking. Sendet der Server erst ein gigantisches 10MB Bild, und eine Mikrosekunde später eine winzige 1KB Text-Nachricht auf demselben Socket an dich, dann muss der Text zwingend warten. Wenn Paket-A des Bildes im Wifi verloren geht, wartet der TCP-Stack, reklamiert das verlorene Bild-Paket, wartet erneut 200ms auf Retransmission, setzt das Bild zusammen, und gibt erst danach den 1KB Text für das JavaScript frei. Dieser massive "Verstopfungs-Fehler" wird erst durch WebTransport (basierend auf HTTP/3 und QUIC/UDP) eliminiert.
Sec-WebSocket-Accept Hashing (Cache Poisoning)
Warum existiert im Handshake dieser obskure Sec-WebSocket-Key?
Das ist keine Verschlüsselung! Es ist ein reiner Schutz gegen deplatzierte HTTP-Caches.
Würde WebSocket dieses Feld weglassen, könnte ein übereifriger Proxy-Server in der Mitte glauben, der Statuscode 101 Switching Protocols wäre eine normale Server-Antwort und könnte diesen cachen. Beim nächsten HTTP-Request eines anderen Users bekäme dieser versehentlich den gecachten Socket-Stream!
Deshalb sendet der Client einen Base64 Nonce-String. Der Server ist serverseitig verpflichtet, diesen String zu nehmen, ihn mit einer weltweit patentierten UUID-Magic-String (258EAFA5-E914-47DA-95CA-C5AB0DC85B11) zu konkatenieren, durch SHA-1 zu jagen und als Sec-WebSocket-Accept zurückzusenden. So ist absolut sichergestellt, dass keine gecachte "Antwort" dazwischengrätscht.
Quick-Check
WSS vs WS?
Wie HTTP vs HTTPS. WSS ist verschlüsselt (TLS). Nutze immer WSS, sonst blockieren Proxies den Traffic oft, weil sie das Protokoll nicht verstehen. Verschlüsselung tunnelt alles durch.Server-Sent Events (SSE)?
Alternative. Nur Server -> Client (Einbahnstraße). Einfacher (reines HTTP), funktioniert besser mit Firewalls. Reicht für Ticker/News. Für Chat/Games braucht man WS.Socket.io?
Eine Library, die WebSockets nutzt, aber Fallbacks hat (Long Polling), falls WS geblockt ist. Fügt Features wie "Auto-Reconnect" und "Rooms" hinzu, die natives WS nicht hat.