Logo GH

WebSockets и SSE

1) Kurz: Was und wofür

WebSocket (WS/WSS) - Upgrade einer HTTP-Verbindung zu einem Full-Duplex-Kanal. Geeignet für Chats, Live-Spiele, Kollaboration, bidirektionale Telemetrie.
Server-Sent Events (SSE) ist ein einseitiger Stream von Server zu Browser (MIME 'text/event-stream'). Ideal für Ticker, Benachrichtigungen, Zitate, Aufgabenfortschritt. Der Kunde ist 'EventSource'.

Auswahlregel:
  • Sie benötigen Eingaben vom Client in Echtzeit (oft und viel) → WebSocket.
  • Nur Push-Updates vom Server, Kompatibilität und Einfachheit sind wichtiger als SSE- →.

2) Netzwerk und Protokolle

2. 1 Transport und Kompatibilität

WebSocket: startet als HTTP 'GET... Upgrade: websocket` (HTTP/1. 1). Für HTTP/2 ist RFC 8441 (CONNECT +': protocol = websocket') möglich, die Unterstützung hängt vom Proxy ab. Funktioniert über TLS (WSS) - obligatorisch in der Produktion.
SSE: die übliche lange HTTP-Antwort ('200 OK') mit Streaming. Es geht wunderbar durch die HTTP/1. 1/2/3, CDN/Proxy-kompatibel (es sei denn, lange Anschlüsse brechen ab).

2. 2 Proxy/Balancer/CDN

Überprüfen Sie: Unterstützung für langlebige Verbindungen, Idla und Timeouts, Sticky-Sitzungen (wenn der Status auf dem Knoten ist).
Für WS: aktivieren Sie' proxy _ read _ timeout', 'upgrade' -Header, Per-Connect-Limits.
Für SSE: Stellen Sie sicher, dass der Proxy die Antwort nicht puffert (andernfalls sieht der Client die Ereignisse nicht rechtzeitig).

3) Nachrichtenmodell und Flusssteuerung

WebSocket: Frame Text oder binär; es gibt 'ping/pong', aber keine eingebaute Backpressure - implementieren Sie auf der Anwendung (Warteschlangen, Fenster, Drop-Policy).
SSE: Textereignisse (UTF-8); Der Client ist in der Lage, mit einer Verzögerung zu reconnect; Server kann 'retry:' setzen. Es gibt 'id:' und die Überschrift 'Last-Event-ID' für die Wiederaufnahme von der gewünschten Position.

Backpressure (allgemeine Praktiken):
  • Kontingentieren Sie ausgehende Nachrichten pro Client.
  • Beschränken Sie die Warteschlange auf nicht zugeführte Ereignisse. Bei Überlauf: Niedrige Priorität verwerfen/aggregieren.
  • Für WS: Verwenden Sie das „Schiebefenster“ und das ACK-Schema auf Anwendungsebene.

4) Zuverlässigkeit der Verbindungen

4. 1 Detektion und Keepalive

WS: Senden Sie' ping 'alle N Sekunden; Timeout-Lücke - reconnect mit exponentiellem Backoff + Jitter.
SSE: Der Server sendet „Kommentare“ ':\n' als Herzschlag, damit die Verbindung nicht als Idle betrachtet wird; Der Kunde wird sich wieder verbinden.

4. 2 Wiederherstellung des Flusses

WS: Halten Sie Offset/Sequenznachrichten und fordern Sie Delta nach reconnect an.
SSE: Verwenden Sie' id: 'für jedes Ereignis und' Last-Event-ID 'in der Anforderung - der Server sendet die fehlenden Ereignisse.

5) Authentifizierung und Autorisierung

Der JWT-Bearer in der Anfrage-URL (WS) ist unsicher (Protokolllecks). Verwenden Sie den Header (über die primäre HTTP-Handshake) oder Cookies mit den Flags' Secure', 'HttpOnly', 'SameSite'.
Sowohl mTLS (speziell für B2B) als auch Signaturen (HMAC) über die ursprüngliche Anfrage sind möglich.
Denken Sie bei SSE mit Cookies an CORS ('Access-Control-Allow-Origin', 'Allow-Credentials').

Token-Rotation: Brechen Sie den Stream nicht ab. Übertragen Sie „bald abgelaufen“ → der Client öffnet die Verbindung mit dem neuen Token.

6) Datenformat und Kompression

WebSocket: permessage-deflate vorsichtig einschalten (CPU); Vermeiden Sie die Kompression von bereits komprimierten Formaten (Proto, Avro). Binäre Payload ist wirtschaftlicher als JSON.
SSE: Dies ist der Text; für große Daten, senden Sie einen Link zu einer REST/gRPC-Ressource oder Chunk-Dateien; transport gzip für SSE - angemessen, aber auf Pufferung im Proxy/CDN achten.

7) Skalierung und Fan-out

7. 1 Horizontale Skalierung

Halten Sie die App für Neustarts fehlerfrei. Der Zustand der Verbindungen ist in der Frontschicht; Die Daten stammen vom Broker.
Sticky (hash by session/user) wird benötigt, wenn es lokale Warteschlangen gibt.
Das Ideal ist eine stateless Front: Der Knoten multiplext nur Abonnements; Ereignisse kommen von einem gemeinsamen pub/sub.

7. 2 Pub/Sub und Makler

Für ein breites Fan-out verwenden Sie Kafka/NATS/Redis Streams.
Die „Fanout Gateway“ -Schicht abonniert die Tops und flufft die Kunden über WS/SSE.
Verwenden Sie einen Routing-Schlüssel (z. B. 'userId', 'matchId'), um die Last zwischen den Knoten auszugleichen.

8) Produktionskonfigs

8. 1 NGINX — WebSocket

nginx map $http_upgrade $connection_upgrade { default upgrade; '' close; }

server {
listen 443 ssl http2;
server_name ws. example. com;

location /ws {
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1. 1;
proxy_read_timeout 75s; # increase for long sessions proxy_send_timeout 15s;
proxy_pass http://ws-backend;
}
}

8. 2 NGINX - SSE (es ist wichtig, die Pufferung zu deaktivieren)

nginx location /events {
proxy_http_version 1. 1;
proxy_set_header Connection "";
proxy_buffering off; # is critical for proxy_cache off threads;
chunked_transfer_encoding on;
proxy_read_timeout 60m;
proxy_pass http://sse-backend;
}

8. 3 Kubernetes (Ingress Annotations, NGINX Ingress)

yaml metadata:
annotations:
nginx. ingress. kubernetes. io/proxy-read-timeout: "3600"
nginx. ingress. kubernetes. io/proxy-send-timeout: "3600"
nginx. ingress. kubernetes. io/enable-websocket: "true"
nginx. ingress. kubernetes. io/proxy-buffering: "off"  # для SSE

9) Codebeispiele

9. 1 SSE Client (Browser)

js const es = new EventSource("/events? channel=odds", { withCredentials: true });

es. addEventListener("message", (e) => {
const data = JSON. parse(e. data);
renderOdds(data);
});

es. addEventListener("error", () => {
//EventSource will reconnect itself; can be shown spinner
});

9. 2 SSE-Server (Node. js/Express)

js app. get('/events', (req, res) => {
res. writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
});
res. write ('retry: 3000\n\n') ;//3s backoff to client

const sub = subscribe(req. query. channel, (event) => {
res. write(`id: ${event. id}\n`);
res. write(`event: message\n`);
res. write(`data: ${JSON. stringify(event. payload)}\n\n`);
});

req. on('close', () => sub. unsubscribe());
});

9. 3 WebSocket Client (Browser)

js const ws = new WebSocket("wss://ws. example. com/ws");
ws. onopen = () => ws. send(JSON. stringify({ type: "join", room: "chat-1" }));
ws. onmessage = (m) => handle(JSON. parse(m. data));
ws. onclose = () => scheduleReconnect();

10) Sicherheit und Begrenzung

Rate limiting per-connection und per-user: Begrenzen Sie die Rate der eingehenden Nachrichten (WS) und die Rate des ausgehenden Datenstroms (WS/SSE).
Quote für die Verbindungslebensdauer und den Gesamtverkehr.
Message size limit и max messages/sec.
WAF/Bot-Filter in der Handshake-Phase; Schutz vor Connection Flooding (viele kurze Anschlüsse).
Isolation durch tenant/namespace: separate Ressourcenpools.

11) Beobachtbarkeit

Metriken:
  • `connections_active`, `connections_new_total`, `bytes_in/out`,
  • `messages_in/out_total`, `dropped_messages_total`,
  • `reconnects_total`, `latency_delivery_ms{p50,p95,p99}`.
  • Protokolle: IP/UA, userId/tenantId, Schließungsgrund ('close _ code'), Dauer.
  • Tracing: Verknüpfen Sie Ereignisse mit dem ursprünglichen Befehl (Korrelations-IDs); Verwenden Sie für WS „virtuelle“ Schlachtfelder.

12) Operative Nuancen

TLS-Terminierung näher am Kunden (CDN/Edge).
Proaktive Gelenkrotation (graceful) bei Deploys: Geben Sie das Flag „wieder verbinden“.
Sharding nach Schlüssel, um die „heißen“ Kanäle gleichmäßig zu verteilen.
Statusbilder für Spätabonnenten (Snapshot + Delta).
Letzter Wert Cache (SSE besonders) - nützlich für einen „kalten“ Client.

13) Anti-Muster

Streamen Sie große binäre Stücke über SSE oder JSON über WS - verwenden Sie den HTTP-Download und den Link in der Nachricht.
Autorisierung nur zum Zeitpunkt der Verbindung und keine Re-Checks in langen Sitzungen.
Globale Sticky unnötig → Ungleichgewichte und „heiße“ Knoten.
Deaktivierte Timeouts/Limits → eingefrorene Verbindungen fressen den Pool auf.
SSE-Proxy/CDN-Pufferung → „Echtzeit“ wird in Minuten der Verzögerung umgewandelt.
Fehlende Sequence/Offset → Nach reconnect verliert der Client die Datenintegrität.

14) Checkliste Umsetzung

  • Modell ausgewählt: WS (bidirektional) oder SSE (einseitig).
  • Timeouts, Keepalive und Reconnect (Backoff + Jitter) sind konfiguriert.
  • Entworfen von sequence/offset und (für SSE) 'id '/' Last-Event-ID'.
  • Sind die Limits Bestimmt: rasmer/skorost/sojedinenija/kwoty, der Schutz von DoS.
  • Config proxy/ingress: upgrade, proxy_buffering off (SSE), read/send timeouts.
  • Skalierung: Pub/Sub-Broker, Fan-Out-Gateway, Sticky nur bei Bedarf.
  • Authentifizierung: sichere Token-Übertragung, klippenlose Rotation.
  • Beobachtbarkeit: Metriken, Protokolle, Traces; Dashboards und Alerts.
  • Releaseplan: graceful-drain der Verbindungen, Signal an den Client über die Rückverbindung.
  • Spieltage: Netzabbrüche, Nodfall, Brokerüberlastung, lange RTTs.

15) FAQ

Kann SSE über CDN zwischengespeichert werden?
Normalerweise nicht: Es handelt sich um einen personalisierten Stream. Für öffentliche Kanäle - vielleicht mit kurzer TTL und Chunked-Delivery, aber es ist einfach, „Echtzeit“ zu knabbern.

Funktioniert WebSocket auf HTTP/2/3?
Der Browser WS startet mit HTTP/1. 1-upgrade; es gibt RFC 8441 für h2, Unterstützung im Proxy/Server ist separat erforderlich. Mit h3 - in Bewegung; Es gibt WebTransport für das Streaming in h3, aber es ist eine andere API.

gRPC vs WS für Browser?
Ein sauberer Browser sagt nicht gRPC; benötigen gRPC-Web über Envoy. Für interaktive Benutzeroberflächen ist WS + REST oft einfacher.

16) Ergebnisse

WebSocket - wenn Sie einen Echtzeit-Dialog und einen kompakten bidirektionalen Kanal benötigen.
SSE - wenn Sie einen einfachen und zuverlässigen Push vom Server zum Client, minimale Komplexität und automatische Rückgewinnung benötigen.
Erfolg in der Produktion sind die richtigen Timeouts und Limits, Erholung von Offset, Pub/Sub-Fan-Out, korrekte Proxy-Einstellungen und klare Beobachtbarkeit.

Contact

Kontakt aufnehmen

Kontaktieren Sie uns bei Fragen oder Support.Wir helfen Ihnen jederzeit gerne!

Telegram
@Gamble_GC
Integration starten

Email ist erforderlich. Telegram oder WhatsApp – optional.

Ihr Name optional
Email optional
Betreff optional
Nachricht optional
Telegram optional
@
Wenn Sie Telegram angeben – antworten wir zusätzlich dort.
WhatsApp optional
Format: +Ländercode und Nummer (z. B. +49XXXXXXXXX).

Mit dem Klicken des Buttons stimmen Sie der Datenverarbeitung zu.