WebSocket in Node.js: Server, Client, Heartbeat und Reconnect

WebSocket in Node.js: ws-Server, eingebauter Client, Heartbeat | We.Inc

Baue einen WebSocket-Server in Node.js mit dem Paket ws, verbinde dich mit dem eingebauten WebSocket-Client von Node, erkenne tote Sockets mit ping und pong und verbinde dich mit Backoff neu.

Node.js hat keinen eingebauten WebSocket-Server, deshalb installieren die meisten Projekte das Paket ws und erstellen einen WebSocketServer. Für die Client-Seite liefert Node ein browserkompatibles globales WebSocket mit, eingeführt in v21.0.0 und v20.10.0, ohne Flag ab v22.0.0 und als stabil markiert ab v22.4.0. Ergänze vor dem Livegang einen Heartbeat mit ping und pong sowie Reconnect mit Backoff.

Welcher Baustein was erledigt

Diese Anleitung baut der Reihe nach einen kleinen Server im Chat-Stil und die Clients, die mit ihm sprechen: einen Server, der Nachrichten zurückschickt und an alle verteilt, ein Node-Skript, das sich ohne jede Abhängigkeit verbindet, einen Heartbeat, der still gestorbene Verbindungen verwirft, und einen Client, der nach einem Server-Neustart zurückkommt. Der Rechner unten zeigt, wie deine Wartezeiten zwischen den Versuchen wachsen, bevor du sie in Code gießt.

Häufige Fragen

Hat Node.js WebSocket eingebaut?

Nur den Client. Die globale WebSocket-Klasse erschien in v21.0.0 und v20.10.0 hinter dem Flag --experimental-websocket, verlor das Flag in v22.0.0 und war ab v22.4.0 nicht mehr experimentell. Einen eingebauten Server gibt es weiterhin nicht, deshalb bleibt ws die übliche Wahl.

Sollte ich ws oder Socket.IO verwenden?

ws spricht das reine WebSocket-Protokoll, daher kann sich jeder Standard-Client verbinden, auch der Browser und das globale WebSocket von Node. Socket.IO setzt ein eigenes Protokoll mit Rooms und automatischem Reconnect obendrauf, braucht aber auf der Gegenseite eine eigene Client-Bibliothek.

Warum sterben Verbindungen ohne close-Event?

Verschwindet ein Netzwerkpfad, etwa weil ein Laptop zugeklappt wird, wird nie ein close-Frame gesendet, und der Server behält einen halb offenen Socket. Der Heartbeat findet diese: Ein Socket, der auf den letzten ping nicht geantwortet hat, wird in der nächsten Runde beendet.

Kann ein Browser-Client pings senden?

Nein. Die Browser-API kennt nur send() und close(). Browser beantworten Server-pings aber von sich aus mit pongs, deshalb funktioniert der serverseitige Heartbeat auch mit Browser-Clients.

Wie teile ich einen Port mit einem HTTP-Server?

Erstelle den HTTP-Server selbst, zum Beispiel mit Express oder node:http, und übergib ihn als new WebSocketServer({ server }). Upgrade-Anfragen gehen an ws, normale Anfragen an deine App.

Wie eine Verbindung beginnt

Heartbeats einfach erklärt

Neu verbinden, ohne den Server zu überrennen

Schritt 1: ein Server mit ws

server.js: Echo und Broadcast

Jede Nachricht wird an alle offenen Clients zurückgesendet. Der error-Listener verhindert, dass ein fehlerhafter Socket den Prozess abstürzen lässt.

Schritt 2: ein Client ohne Abhängigkeiten

client.js: das globale WebSocket von Node

Läuft unverändert ab Node 22 und in einer Browser-Konsole, weil beide dieselbe WebSocket-Klasse bereitstellen.

Schritt 3: tote Verbindungen mit ping und pong entfernen

Unsere Version des Musters aus der README von ws: bei pong als lebendig markieren, alles beenden, was die letzte Runde verpasst hat.

Schritt 4: ein Client, der sich neu verbindet

reconnect.js: exponentieller Backoff mit Jitter

Die Wartezeit verdoppelt sich nach jedem Fehlversuch bis zu einer Obergrenze, bekommt eine zufällige Streuung und wird zurückgesetzt, sobald eine Verbindung steht.

Hinter nginx

nginx reicht das Upgrade nur durch, wenn du die Header Upgrade und Connection selbst weiterleitest. Vor nginx 1.29.7 brauchst du außerdem proxy_http_version 1.1.

nginx-location für den Socket

proxy_read_timeout hebt das Idle-Limit von 60 Sekunden an, der Heartbeat oben hält den Datenverkehr ohnehin am Laufen.

Rechner für Reconnect-Wartezeiten

Lege eine erste Wartezeit, einen Multiplikator und eine Obergrenze fest, um zu sehen, wie lange ein Client vor jedem Versuch wartet, und die kürzeste und längste Wartezeit mit Jitter.

Erste Wartezeit (ms)

Multiplikator

Obergrenze (ms)

Angezeigte Versuche

Jitter hinzufügen (zwischen halber und voller Wartezeit warten)

Wartezeit vor jedem Reconnect-Versuch

Versuch

Wartezeit

Mit Jitter

Bisher insgesamt gewartet

{n} bis {v} s

Dieselben Einstellungen als Code

Kostenlos starten · Keine Kreditkarte nötig

Verwandt: Ratgeber

Produkt

Für wen

Funktionen

Ressourcen

Unternehmen

Sitemap