WebSocket Streams und Events
TL; DR
Work Stream = Trusted Channel (WSS) + zusammenfassende Offsets + idempotente Events + strikte Limits und Backpressure. Do: JWT-Authentifizierung, Autorisierung für Topiks, Heartbeats, seq/offset + resume-token, at-least-once + dedup. Für den Maßstab - Sharding durch User/Tenant, Sticky Routing und Queue (Kafka/NATS/Redis Streams) als Quelle der Wahrheit.
1) iGaming Business Cases (was wirklich gestreamt wird)
Balance/Limits: Sofortige Änderungen der Balance, RG Limits, Sperren.
Wetten/Runden/Ergebnisse: Bestätigung, Status, Berechnung der Gewinne.
Turniere/Leaderboards: Positionen, Timer, Preisveranstaltungen.
Zahlungen: Auszahlungs-/Refund-Status, KYC/AML-Flags - als Benachrichtigungen (und Kritik bleibt in REST + Webhooks).
Service-Events: Chat-Nachrichten, Push-Banner, Sitzungsstatus, Wartung.
2) Protokoll und Verbindung
Nur WSS (TLS 1. 2+/1. 3). Maximal 1 aktive Verbindung pro Gerät/Standardsitzung.
Ping/Pong: Der Client sendet „ping“ alle 20-30 s, Antwort-Timeout 10 s. Der Server setzt die Verbindung bei 3 Timeouts hintereinander zurück.
Kompression: 'permessage-deflate', Begrenzung der Rahmengröße (z.B. ≤ 64 KB).
Payload-Format: JSON für extern, Protobuf/MsgPack für intern/mobil.
3) Authentifizierung und Autorisierung
Handshake mit JWT in query/header ('Sec-WebSocket-Protocol '/' Authorization'), TTL-token kurz (≤ 15 min), refresh durch out-of-band (REST).
Tenant-scoped claims: `sub`, `tenant`, `scopes`, `risk_flags`.
ACL to Topics/Channels: Abonniere nur die erlaubten 'topic' (z.B.: 'user: {id}', 'tournament: {id}', 'game: {table}').
Neuaufbau der Verbindung bei Ablauf des Tokens: „Soft Window“ 60s.
4) Abonnementmodell
Der Client sendet nach der Verbindung Befehle:json
{ "op":"subscribe", "topics":["user:123", "tournament:456"], "resume_from":"1748852201:987654" }
{ "op":"unsubscribe", "topics":["tournament:456"] }
'resume _ from' ist ein Offset (siehe § 5), wenn der Client die Verbindung wieder herstellt.
Der Server antwortet mit ack/nack, nicht eingelaufene ACLs in 'nack' mit 'reason'.
5) Liefergarantien und Zusammenfassung
Ziel: at-least-once pro Kanal + Idempotenz beim Kunden.
Jedes Ereignis hat eine monotone' seq 'innerhalb eines' part' (in der Regel user/room) und eine globale' event _ id 'für das Deduplex.
Beim Re-Connect übermittelt der Kunde' resume _ from'= die zuletzt bestätigte' seq'(oder 'offset' des Brokers). Der Server lädt verpasste Ereignisse aus der „Quelle der Wahrheit“ (Kafka/NATS/Redis Streams).
Wenn die Verzögerung größer als die Retention ist (z.B. 24 h), sendet der Server einen "Snapshot' -Status und einen neuen" seq ".
- Speichern Sie' last _ seq '/' event _ id 'im durable-Speicher (IndexedDB/Keychain).
- Dedup durch 'event _ id', Überspringen von Ereignissen mit 'seq ≤ last_seq', Erkennen von Löchern (gap) → Auto-resync' Snap-Shot-Abfrage.
6) Nachrichtenschema (envelope)
json
{
"ts": "2025-11-03T12:34:56. 789Z",
"topic": "user:123",
"seq": "1748852201:987654", // partition:offset
"event_id": "01HF..", // UUID/KSUID
"type": "balance. updated",
"data": { "currency":"EUR", "delta"--5. 00, "balance":125. 37 },
"trace_id": "4e3f.., "//for correlation
"signature": "base64 (hmac (...)) "//optional for partners
}
'type' ist eine Domain-Taxonomie (siehe Event Dictionary).
PII/PCI - Ausschließen/Maskieren auf Gateway-Ebene.
7) Backpressure, Quoten und Schutz vor „teuren“ Kunden
Server → Client: per-connection send-queue mit „Schiebefenster“. Überfüllt - Zurücksetzen von Abonnements auf „laute“ Topics oder Disconnect mit dem Code' 1013 '/' policy _ violation'.
Client → Server: Limits für 'subscribe/unsubscribe' (z.B. ≤ 10/sec), Begrenzung der Topic-Liste (≤ 50), Mindestabonnementwiederholungsintervall.
Rate limits per IP/tenant/key. Anomalien → vorübergehende Blockierung.
Priorität: Vitalereignisse (Balance, RG-Limits) - Prioritätswarteschlange.
8) Schutz und Sicherheit
WAF/Bot-Profil auf Handshake Endpoint, Liste der erlaubten Herkunft.
mTLS zwischen Edge-Gateway und Stream-Knoten.
DoS-Schutz: SYN-Cookies auf L4, Limits für die Anzahl der offenen WS/Keep-Alive-Intervall.
Anti-Replay: 'timestamp' in der optionalen Payload-Signatur (für Partner) mit einem gültigen Fenster von 5 min.
Isolierung der Mieter: physisches/logisches Sharding, Schlüssel/Token per tenant.
9) Verkehrsarchitektur
Gateway (Edge): TLS-Terminal, authN/Z, Kontingente, Routing pro Partei.
Stream-Knoten: Stateless-Worker mit Sticky-Routing durch 'Hash (user_id)% N'.
Event Broker: Kafka/NATS/Redis Streams - Quelle der Wahrheit und Replay-Puffer.
State-Service: speichert Snapshots (Balance, Positionen im Turnier).
Multi-Region: Vermögenswert; GSLB für die nächstgelegene Region; Home-Region wird mit dem Login gesichert; bei Failover ein „kalter“ Lebenslauf aus einer anderen Region.
10) Ordnung, Kohärenz, Idempotenz
Die Ordnung ist innerhalb der Partei (Benutzer/Raum) garantiert, nicht global.
Konsistenz: Das Ereignis kann vor der REST-Antwort kommen; UX muss in der Lage sein, mit einem Zwischenzustand (optimistische UI + Reconciliation) zu leben.
Idempotenz: Die erneute Verarbeitung von 'event _ id' ändert nichts am Zustand des Clients.
11) Fehler, reconnect und „Sturm“
Schließcodes: „1000“ (normal), „1008“ (policy), „1011“ (intern), „1013“ (Server-Overload).
Kunden exponentieller Backoff + Jitter: 1s, 2s, 4s... max. 30s.
Während der Massenrekonstruktion („thundering herd“) gibt der Server „retry _ after“ und „graue“ Antworten mit der Aufforderung, SSE-Fallback für Read-Only zu verwenden.
12) Cache und Schnappschüsse
Jedes Abonnement kann mit einem aktuellen Snapshot beginnen, gefolgt von einem Fluss von Diff-Events.
Versionierung des Schemas' data _ version 'und Kompatibilität (die Erweiterung der Felder macht die Clients nicht kaputt).
13) Beobachtbarkeit und SLO
Metriken:- Verbindungen: aktiv, etabliert/sec, Verteilung nach Mieter/Region.
- Lieferung: p50/p95 Verzögerung vom Broker zum Kunden, Drop-Rate, Resend-Rate.
- Zuverlässigkeit: Anteil erfolgreicher Zusammenfassungen ohne Snapshot, Gap-Detektor.
- Fehler: 4xx/5xx auf Handshake, Schließcodes, Limit-Hits.
- Last: RPS-Befehle' subscribe', Warteschlangengröße, CPU/NET.
- WS p95 ≤ 500 ms (innerhalb der Region)
- Ende-zu-Ende-Latenz des Ereignisses p95 ≤ 300 ms (Benutzerpartition).
- Resume success ≥ 99%, message loss = 0 (по at-least-once).
- Uptime-Stream-Endpunkt ≥ 99. 95%.
14) Schaltplan- und Versionsmanagement
Event-Wörterbuch mit Besitzern, Beispielen und Semantik.
„Weiche“ Evolution: nur optionale Felder hinzufügen; Löschen - nach'@ deprecated 'Zeitraum.
Vertragstests gegen Client SDKs, Linters auf JSON Schema/Protobuf.
15) Incident Playbooks (in Ihr gesamtes Playbook einbetten)
Latenzwachstum: Wechseln Sie die Parteien zu Reserveknoten, erhöhen Sie die Batch-Größe beim Broker, aktivieren Sie die Priorisierung wichtiger Ereignisse.
Sturm der Rückeroberung: 'retry _ after' aktivieren, Handshake-Limits vorübergehend anheben, SSE-Vollback einschalten.
Token-Leak: JWKS-Rotation, Rückruf betroffener Token, erzwungenes Reconnect mit re-auth.
Verlust der Broker-Partei: Übertragung in den Snap-Modus, Replikate nach der Wiederherstellung.
16) Mini-API-Spezifikation (vereinfacht)
Handshake (HTTP GET → WS):
GET /ws? tenant=acme&client=web
Headers:
Authorization: Bearer <JWT>
X-Trace-Id: <uuid>
Kundenbefehle:
json
{ "op":"subscribe", "topics":["user:123"], "resume_from":"1748852201:42" }
{ "op":"unsubscribe", "topics":["user:123"] }
{ "op":"ping", "ts":"2025-11-03T12:34:56Z" }
Serverantworten:
json
{ "op":"ack", "id":"subscribe:user:123" }
{ "op":"event", "topic":"user:123", "seq":"1748852201:43", "type":"balance. updated", "data":{...} }
{ "op":"snapshot", "topic":"user:123", "seq":"1748852201:42", "state":{...} }
{ "op":"error", "code":"acl_denied", "reason":"no access to topic tournament:456" }
{ "op":"pong", "ts":"..." }
17) UAT-Checkliste
- Zusammenfassung aus dem Offset nach 1/10/60 Minuten Downtime des Kunden.
- Dedup: Die erneute Lieferung der gleichen 'event _ id' ändert nicht den Status.
- Gap-Detektor → automatische "snapshot' und Ausrichtung.
- Kontingente und Backpress: Der geladene Client erhält policy-disconnect.
- Multiregion: Failover der Region unter Beibehaltung des Offset.
- Sicherheit: Token-Rocker, abgelaufener JWT, Versuch eines Abonnements außerhalb der ACL.
- RG/Balance Ereignisse kommen vor/nach REST - UI korrekt „stitching“.
18) Häufige Fehler
Es gibt keine' seq/offset 'und Wiederaufnahme - wir verlieren Ereignisse und Vertrauen.
Mischen Sie kritische Zahlbefehle in WS-Mutationen - verwenden Sie REST.
Keine Backpress/Quoten - „abgehängte“ Verbindungen und eine Speicher-Lawine.
Globale Ordnung - teuer und unnötig; Ordnung in der Partei genügt.
Protokollierung von PII in Ereignissen - Verletzung der Privatsphäre und PCI/GDPR.
Mangel an Ereigniswörterbuch und Versionierung - Kunden brechen zusammen.
Zusammenfassung
WebSocket-Streams liefern reaktive UX- und Online-Signale, wenn sie als zusammenfassender, geschützter und begrenzter Kanal aufgebaut sind: WSS + mTLS/JWT, ACL auf Topics, seq/offset + resume, at-least-once mit Deduple, Backpressure/Quotas, Broker als Quelle der Wahrheit, Beobachtbarkeit und SLO. So bleiben die Streams für den Nutzer schnell und für die Plattform überschaubar - ohne Kompromisse bei Sicherheit und Geld.