WebSocket striam ed eventi
TL; DR
Strim di lavoro = canale affidabile (WSS) + offset riassumibili + eventi idompotenti + limiti rigorosi e backpressure. Fare: autenticazione JWT, autorizzazioni su topic, heartbeats, seq/offset + resume-token, at-least-once + deadup. Per la scala - Sharding user/tenant, sticky routing, e la coda (Kafka/NATS/Redis Streams) come fonte di verità.
1) Valigette aziendali iGaming (che è reale)
Bilanci/limiti: modifiche istantanee, limiti RG, blocchi.
Scommesse/round/risultati: conferma, stato, calcolo delle vincite.
Tornei/liderboard: posizioni, timer, eventi premio.
Pagamenti: stato payout/refund, bandiere KYC/AML - come notifiche (e le critiche rimangono in REST. + web hub).
Eventi di servizio: messaggi chat, banner push, stati sessione, maintenance.
2) Protocollo e connessione
Solo WSS (TLS 1. 2+/1. 3). Massimo 1 connessione attiva al dispositivo/sessione predefinita.
Ping/Pong: il client invia «ping» ogni 20-30 s, tempo di risposta 10 c. Il server ripristina la connessione a 3 timeout consecutivi.
Compressione: «permessage-deflate», limite per la dimensione del fotogramma (ad esempio, ≤ 64 KB).
Formato di carico utile: JSON per esterni, Protobuf/MsgPack per interni/mobili.
3) Autenticazione e autorizzazione
Handshake con JWT in query/header ('Sec-WebSocket-Protocol '/' Authorization'), TTL token breve (≤ 15 min), refresh per out-of-band (REST).
Tenant-scoped claims: `sub`, `tenant`, `scopes`, `risk_flags`.
ACL su topic/canali - Abbonamento solo a «topic» autorizzati (ad esempio: «user: {id}», «turnement: {id}», «game: {table}»).
Reindirizzare la connessione al termine del token a 60 secondi.
4) Modello di sottoscrizioni
Il client invia i comandi dopo il connect:json
{ "op":"subscribe", "topics":["user:123", "tournament:456"], "resume_from":"1748852201:987654" }
{ "op":"unsubscribe", "topics":["tournament:456"] }
'resume _ from' - offset (vedere l'articolo 5) se il client ripristina la connessione.
Il server risponde con ack/nack senza ACL in nack con reason.
5) Garanzia di consegna e riepilogo
Obiettivo: at-least-once per canale + idampotenza del cliente.
Ogni evento ha un «seq» monotono all'interno della partitura (solitamente user/room) e un «event _ id» globale per la deduplicazione.
In un re-connettore, il client trasmette «resume _ from» = l'ultimo «seq» (o «offset» broker) confermato. Il server riceve gli eventi mancanti dall'origine della verità (Kafka/NATS/Redis Streams).
Se la lega supera la retentione (ad esempio 24 ore), il server invia «snapshot» allo stato e al nuovo «seq».
- Memorizza «last _ seq »/« event _ id» in un repository durable (IndexedDB/Keychain).
- Deadup dì event _ id ", omettere gli eventi da" seq n'last _ seq ", rilevare i buchi (gap) da" resync "automatico della richiesta di snapshot.
6) Schema di messaggio (invelope)
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» è una tassonomia di dominio (vedere dizionario eventi).
PII/PCI - Escludi/maschera a livello di gateway.
7) Backpressure, quote e protezione da client «costosi»
Server → Client: per-connection send-queue con «finestra scorrevole». Sovraccarico: reimpostazione di iscrizioni a topic «rumorosi» o disconnect con codice «1013 »/« policy _ violation».
Client → Server: limiti per «subscribe/unsubscribe» (ad esempio, ≤ 10/secondi), limitazione dell'elenco dei topic (≤ 50), intervallo minimo di riiscrizione.
Rate limits su IP/tenant/chiave. Anomalie. Blocco temporaneo.
Priority - Eventi essenziali (bilanciamento, limiti RG) - Coda prioritaria.
8) Protezione e sicurezza
Profilo WAF/bot su handshake endpoint, elenco di autorizzati Origin.
mTLS tra l'edge-gateway e gli strim-nodi.
Protezione DoS: cookie SYN su L4, limiti per numero di WS aperti/intervallo keep-alive.
Anti-replay: «timestamp» nella firma opzionale di carico utile (per i partner) con una finestra valida di 5 minuti
Isolamento degli affittuari: Charding fisico/logico, chiavi/token per-tenant.
9) Architettura dei trasporti
Gateway (edge) - Terminate TLS, authN/Z, quote, instradamento alla partitura.
Stream: storeless worker con sticky routing per «hash (user _ id)% N».
Broker di eventi: Kafka/NATS/Redis Streams - fonte di verità e repliche-buffer.
Servizio state - memorizza snapshot (bilancia, posizioni nel torneo).
Multiregion: risorsa; GSLB per la regione più vicina; home-region viene vincolato al login Il feelover è un freddo da un'altra regione.
10) Ordine, coerenza, idepotenza
L'ordinamento è garantito all'interno della partitura (user/room), non globalmente.
Consistenza: l'evento può arrivare prima della risposta REST. UX deve essere in grado di vivere con uno stato intermedio (ottimistico UI + recordation).
Idempotenza: la rielaborazione dì event _ id "non cambia lo stato del client.
11) Errori, riavnect e tempesta
Codici di chiusura: '1000' (normale), '1008' (policy), '1011' (internal), '1013' (server overload).
Client backoff esponenziale + jitter: 1s, 2s, 4s... Max 30s.
Durante i ricollocamenti di massa («thundering herd»), il server dà risposte «retry _ after» e «grigie» con suggerimento di utilizzare SSE fallback per il read-only.
12) Cache e snapshot
Ogni sottoscrizione può iniziare con uno stato aggiornato, quindi con un flusso di eventi diff.
Versioning dello schema dì data _ version "e compatibilità (l'estensione dei campi non rompe i client).
13) Osservabilità e SLO
Metriche:- Connessioni attive, installate/secondi, distribuite per affittacamere/regioni.
- Consegna: p50/p95 ritardi dal broker al cliente, drop-rate, resend-rate.
- Affidabilità: percentuale di risultati senza snapshot, rilevatore gap.
- Errori: 4xx/5xx su handshake, codici di chiusura, limiti di successo.
- Carico: RPS comandi subscribe, dimensioni code, CPU/NET.
- Installare WS p95 da 500 ms (all'interno della regione).
- End-to-end latency eventi p95-300 ms (user-partition).
- Resume success ≥ 99%, message loss = 0 (по at-least-once).
- Uptime strame-endpoint ≥ 99. 95%.
14) Gestione di schemi e versioni
Un dizionario di eventi con proprietari, esempi e semantici.
Evoluzione «morbida»: solo aggiunta di campi opzionali l'eliminazione è dopo il periodo «@ deprecated».
Test contrattuali contro SDK client, linter su JSON Schema/Protobuf.
15) Playbook incidenti (incorporare nel vostro playbook comune)
Crescita latency: passare le partenze ai nodi di riserva, aumentare la dimensione batch del broker, attivare la priorità degli eventi vitali.
Tempesta di richiamo: attivare «retry _ after», alzare temporaneamente i limiti handshake, attivare il follback SSE.
Fuga di token: rotazione JWKS, ritiro dei token interessati, forzatura di reconnect con re-auth.
Perdita della partitella del broker: messa in modalità snapshot, repliche dopo il recupero.
16) Mini-specifica API (semplificata)
Handshake (HTTP GET → WS):
GET /ws? tenant=acme&client=web
Headers:
Authorization: Bearer <JWT>
X-Trace-Id: <uuid>
Comandi client:
json
{ "op":"subscribe", "topics":["user:123"], "resume_from":"1748852201:42" }
{ "op":"unsubscribe", "topics":["user:123"] }
{ "op":"ping", "ts":"2025-11-03T12:34:56Z" }
Risposte server:
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) Foglio di assegno UAT
- da off-set dopo 1/10/60 minuti di downtime del cliente.
- Deadup: la ripartenza dello stesso «event _ id» non cambia lo stato.
- Rilevatore GAP automatico «snapshot» e allineamento.
- Quote e backpressure: il client carico riceve policy-disconnect.
- Multiregion: regione failover con mantenimento offset.
- Sicurezza: token rocker scaduto JWT, tentativo di sottoscrizione fuori ACL.
- RG/bilanciamento eventi vengono prima/dopo REST- UI correttamente «cucito».
18) Errori frequenti
No seq/offset e riparte - Perdiamo eventi e fiducia.
Miscelare i comandi di pagamento critici nelle mutazioni WS: utilizzare REST.
Nessuna backpressure/quote - Connessioni sospese e una valanga di memoria.
L'ordinamento globale è costoso e non è necessario; C'è abbastanza ordine nella partitella.
La logica PII negli eventi - violazioni della privacy e PCI/GDPR.
Nessun dizionario eventi e versioning - I clienti si rompono.
Riepilogo
WebSocket-striam dà il reattivo UX e segnali operativi se sono costruiti come canale riassunto, protetto e limitato: ACL su topic, seq/offset + resume, at-least-once con deducibile, backpressure/quote, broker come fonte di verità, osservabilità e SLO. Così gli striam rimangono veloci per l'utente e gestibili per la piattaforma, senza compromessi sulla sicurezza e sul denaro.