Logo GH

WebSockets и SSE

1) Kısa: ne ve ne için

WebSocket (WS/WSS) - HTTP bağlantısı tam çift yönlü kanala yükseltilir. Sohbetler, canlı oyunlar, işbirliği, çift yönlü telemetri için uygundur.
Sunucu Tarafından Gönderilen Olaylar (SSE) - sunucudan tarayıcıya tek yönlü akış (MIME 'text/event-stream'). İşaretçiler, bildirimler, alıntılar, görev ilerlemesi için idealdir. İstemci - 'EventSource'.

Seçim kuralı:
  • Gerçek zamanlı olarak istemciden girişe ihtiyacınız var (genellikle çok) - WebSocket.
  • Sadece sunucudan gelen push güncellemeleri, uyumluluk ve basitlik SSE'den daha önemlidir.

2) Ağ ve protokoller

2. 1 Taşıma ve uyumluluk

WebSocket: HTTP 'GET'olarak başlar... Yükseltme: Websocket '(HTTP/1. 1). HTTP/2 için, RFC 8441 (CONNECT + ': protocol = websocket') mümkündür, destek proxy'ye bağlıdır. TLS (WSS) üstünde çalışır - satışlarda zorunludur.
SSE: akış ile normal uzun HTTP yanıtı ('200 OK'). HTTP/1 boyunca iyi gider. 1/2/3, CDN/proxy ile uyumludur (uzun bağlantılar sonlandırılmazsa).

2. 2 Proxy/dengeleyici/CDN

Kontrol: Uzun ömürlü bağlantılar, boşluklar ve zaman aşımları, yapışkan oturumlar için destek (durum düğümde ise).
WS için: 'proxy _ read _ timeout', 'upgrade' başlıkları, bağlantı başına sınırları içerir.
SSE için, proxy'nin yanıtı arabelleğe almadığından emin olun (aksi takdirde istemci olayları zamanında görmez).

3) Mesaj modeli ve akış kontrolü

WebSocket: metin veya ikili çerçeveler; Bir 'ping/pong' var, ancak yerleşik bir geri basınç yok - uygulamada uygulayın (kuyruklar, pencereler, bırakma politikası).
SSE: metin olayları (UTF-8); İstemci yerleşik bir gecikme ile yeniden bağlanabilir; Sunucu 'retry:' belirleyebilir. İstenen konumdan devam etmek için bir'id:'ve bir "Last-Event-ID" başlığı vardır.

Backpressure (genel uygulamalar):
  • Müşteri başına giden mesajları alıntılayın.
  • Gönderilmeyen olayların sırasını sınırlayın; taşma üzerinde - düşük öncelikli/agrega atın.
  • WS için, sürgülü bir pencere ve uygulama düzeyinde bir ACK kullanın.

4) Bağlantıların güvenilirliği

4. 1 Algılama ve keepalive

WS: her N saniyede bir 'ping' gönder; Zaman aşımı boşluğu - üstel geri dönüş + jitter ile yeniden bağlanın.
SSE: sunucu "comments" ':\n' kalp atışı olarak gönderir, böylece bağlantı boşta sayılmaz; Müşteri kendini yeniden bağlar.

4. 2 Akış kurtarma

WS: ofset/sekans mesajlarını saklayın ve yeniden bağlandıktan sonra delta isteyin.
SSE: Her olay için'id:'ve istekte 'Last-Event-ID' kullanın - sunucu kaçırılan olayları gönderir.

5) Kimlik doğrulama ve yetkilendirme

İstek URL'sinde (WS) JWT Taşıyıcı güvensizdir (günlüklere sızar). Bir başlık (birincil HTTP el sıkışma yoluyla) veya 'Güvenli', 'HttpOnly', 'SameSite' bayrakları olan çerezler kullanın.
mTLS (özellikle B2B için) ve orijinal istek üzerine imzalama (HMAC) mümkündür.
Çerezli SSE için, CORS ('Access-Control-Allow-Origin', 'Allow-Credentials') hakkında bilgi edinin.

Token rotasyonu: Akışı kesmeyin. Pass "yakında sona erecek" - istemci yeni belirteç ile bağlantıyı yeniden açacaktır.

6) Veri formatı ve sıkıştırma

WebSocket: Permessage-deflate'i dikkatlice etkinleştirin (CPU); Zaten sıkıştırılmış formatların (Proto, Avro) sıkıştırılmasından kaçının. İkili yük JSON'dan daha ekonomiktir.
SSE: bu metin; Büyük veriler için, bir REST/gRPC kaynağına veya yığın dosyalarına bir bağlantı gönderin; SSE için taşıma gzip - uygun, ancak proxy/CDN'de tamponlama için izleyin.

7) Ölçeklendirme ve fan çıkışı

7. 1 Yatay ölçekleme

Yeniden başlatmalar için uygulamayı hatasız tutun. Bağlantı durumu - ön katmanda; veri - komisyoncudan.
Yerel kuyruklar varsa yapışkan (oturuma/kullanıcıya göre karma) gereklidir.
İdeal, vatansız cephedir: düğüm sadece abonelikleri çoğaltır; Etkinlikler ortak bir pub/sub'dan gelir.

7. 2 Pub/Sub ve Brokerler

Geniş bir fan çıkışı için Kafka/NATS/Redis Streams kullanın.
"Fanout Gateway" katmanı konulara abone olur ve WS/SSE aracılığıyla müşterileri kabartır.
Düğümler arasındaki yükü dengelemek için bir yönlendirme anahtarı (örneğin, 'userId', 'matchId') kullanın.

8) Üretim yapılandırmaları

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 (arabelleklemeyi devre dışı bırakmak için önemlidir)

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 (Giriş Ek Açıklamaları, NGINX Girişi)

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) Kod örnekleri

9. 1 SSE istemcisi (tarayıcı)

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 sunucusu (Düğüm. 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 istemcisi (tarayıcı)

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) Güvenlik ve sınırlama

Bağlantı başına ve kullanıcı başına hız sınırlaması: gelen mesajların hızını (WS) ve giden akış hızını (WS/SSE) sınırlayın.
Bağlantı ömrü ve toplam trafiğe göre kota.
Mesaj boyutu sınırı и maksimum mesaj/sn.
El sıkışma aşamasında WAF/bot filtreleri; Bağlantı taşmalarına karşı koruma (birçok kısa bağlantı).
Kiracı/ad alanı yalıtımı: bireysel kaynak havuzları.

11) Gözlemlenebilirlik

Metrikler:
  • 'connections _ active', 'connections _ new _ total', 'bytes _ in/out',
  • 'mesajlar _ in/out _ total', 'drop _ messages _ total',
  • 'reconnects _ total', 'latency _ delivery _ ms {p50, p95, p99}'.
  • Loglar: IP/UA, userId/tenantId, kapatma nedeni ('close _ code'), süre.
  • İzleme: olayları orijinal komutla ilişkilendirme (korelasyon kimlikleri); WS için'sanal "butch spans kullanın.

12) Operasyonel nüanslar

TLS sonlandırma istemciye daha yakın (CDN/edge).
Tükenme sırasında bağlantıların proaktif dönüşü (zarif): bayrağa "yeniden bağlanma" sağlar.
"Sıcak" kanalları eşit olarak dağıtmak için anahtar üzerinde sharding.
Geç aboneler için durum anlık görüntüleri (snapshot + delta).
Son değer önbelleği (özellikle SSE) - soğuk istemci için kullanışlıdır.

13) Anti-desenler

WS üzerinden SSE veya JSON aracılığıyla büyük ikili parçaları akış - HTTP indirme kullanın ve mesajdaki bağlantıyı kullanın.
Yalnızca bağlantı sırasında yetkilendirme ve uzun oturumlar için yeniden kontrollerin olmaması.
Küresel yapışkan gereksiz yere - dengesizlik ve sıcak düğümler.
Devre dışı bırakılmış zaman aşımları/limitler - donmuş bağlantılar havuzu tüketir.
SSE proxy/CDN arabelleğe alma - "gerçek zamanlı" gecikme dakikaları olur.
Sekans/ofset eksikliği - yeniden bağlandıktan sonra, istemci veri bütünlüğünü kaybeder.

14) Uygulama kontrol listesi

  • WS (çift yönlü) veya SSE (tek taraflı) seçilir.
  • Yapılandırılmış zaman aşımları, keepalive ve yeniden bağlanma (backoff + jitter).
  • Tasarlanmış dizi/ofset ve (SSE için)'id'/' Last-Event-ID '.
  • Boyut/hız/bağlantılar/kotalar, DoS koruması tanımlanmıştır.
  • Proxy/ingress config: yükseltme, proxy_buffering (SSE), okuma/gönderme zaman aşımları.
  • Ölçekleme: pub/sub broker, fan-out ağ geçidi, sadece gerekirse yapışkan.
  • Kimlik doğrulama: güvenli belirteç aktarımı, kesintisiz dönüş.
  • Gözlemlenebilirlik: metrikler, günlükler, izler; gösterge panoları ve uyarılar.
  • Serbest bırakma planı: zarif drenaj bağlantıları, istemciye yeniden bağlanması için sinyal verir.
  • Oyun Günleri: ağ sonları, düğüm damlaları, broker aşırı yüklemesi, uzun RTT'ler.

15) SSS

SSE CDN ile önbelleğe alınabilir mi?
Genellikle değil: Bu kişiselleştirilmiş bir akış. Kamu kanalları için - muhtemelen kısa TTL ve chunked-teslimat ile, ancak "gerçek zamanlı" kırmak kolaydır.

WebSocket HTTP/2/3 üstünde çalışıyor mu?
Tarayıcı WS HTTP/1 ile başlar. 1-yükseltme; H2 için RFC 8441 vardır, proxy/sunucuda destek ayrıca gereklidir. H3 ile - hareket halinde; Akış için, h3 WebTransport'a sahiptir, ancak farklı bir API'dir.

Tarayıcı için gRPC vs WS?
Temiz bir tarayıcı gRPC demez; Elçi aracılığıyla gRPC-Web gerekir. Etkileşimli UI'ler için, WS + REST genellikle daha kolaydır.

16) Toplam

WebSocket - gerçek zamanlı diyaloğa ve kompakt bir çift yönlü kanala ihtiyacınız olduğunda.
SSE - sunucudan istemciye basit ve güvenilir bir itmeye ihtiyacınız olduğunda, minimum karmaşıklık ve otomatik yeniden bağlantı.
Satışlardaki başarı, doğru zaman aşımları ve sınırlar, ofsetten kurtarma, pub/alt fan çıkışı, doğru proxy ayarları ve net gözlemlenebilirliktir.

Contact

Bizimle iletişime geçin

Her türlü soru veya destek için bize ulaşın.Size yardımcı olmaya her zaman hazırız!

Telegram
@Gamble_GC
Entegrasyona başla

Email — zorunlu. Telegram veya WhatsApp — isteğe bağlı.

Adınız zorunlu değil
Email zorunlu değil
Konu zorunlu değil
Mesaj zorunlu değil
Telegram zorunlu değil
@
Telegram belirtirseniz, Email’e ek olarak oradan da yanıt veririz.
WhatsApp zorunlu değil
Format: +ülke kodu ve numara (örneğin, +90XXXXXXXXX).

Butona tıklayarak veri işlemenize onay vermiş olursunuz.