WebSockets и SSE
1) Кыскача: эмне жана эмне үчүн
WebSocket (WS/WSS) - толук дуплекстүү каналга HTTP байланышын жаңыртуу. чат, Live оюндар, кызматташуу, эки тараптуу телеметрия үчүн ылайыктуу.
Server-Sent Events (SSE) - серверден браузерге (MIME 'text/event-stream') бир тараптуу агым. Тикерлер, билдирүүлөр, котировкалар, тапшырмалардын жүрүшү үчүн идеалдуу. Кардар - 'EventSource'.
- Бизге кардардан реалдуу убакыт режиминде киргизүү керек (көп жана көп) → WebSocket.
- Гана Server Push-Updates, шайкештиги жана жөнөкөйлүгү маанилүү → SSE.
2) Тармак жана протоколдор
2. 1 Транспорт жана шайкештик
WebSocket: HTTP 'GET катары башталат... Upgrade: websocket` (HTTP/1. 1). HTTP/2 үчүн RFC 8441 (CONNECT + ': protocol = websocket') мүмкүн, колдоо прокси көз каранды. Ал TLS (WSS) үстүнөн иштейт - сөзсүз түрдө.
SSE: кадимки узакка созулган HTTP жооп ('200 OK') агымы менен. Жакшы HTTP/1 аркылуу өтөт. 1/2/3, CDN/прокси менен шайкеш келет (эгерде узун байланыштар үзүлбөсө).
2. 2 Proxy/баланстагыч/CDN
Текшерип көрүңүз: узак мөөнөттүү байланыштарды, IDL жана таймдарды, sticky-сессияларды (эгерде байлык түйүндө болсо) колдоо.
WS үчүн: 'proxy _ read _ timeout', 'upgrade' -заголовкаларды, per-connection лимиттерин киргизиңиз.
SSE үчүн: Proxy жоопту буферлебегенине ынаныңыз (антпесе кардар окуяларды өз убагында көрбөйт).
3) Билдирүү модели жана агым башкаруу
WebSocket: кадр текст же бинардык; 'ping/pong' бар, бирок орнотулган backpressure жок - тиркемеде ишке ашырыңыз (кезек, терезелер, drop-policy).
SSE: тексттик окуялар (UTF-8); кардар ички кечигүү менен reconnect алат; сервер 'retry:' деп коюшу мүмкүн. Бар 'id:' жана аталышы 'Last-Event-ID' туура позициядан кайра баштоо үчүн.
- Чыгуучу билдирүүлөрдү per-кардарга квота.
- Жазылбаган окуялардын кезегин чектөө; толуп кеткенде - төмөн артыкчылыктарды ыргытуу/агрегациялоо.
- WS үчүн: колдонмо деңгээлинде "жылма терезени" жана ACK схемасын колдонуңуз.
4) байланыш ишенимдүүлүгү
4. 1 Детекция жана keepalive
WS: ар бир N секунд 'ping' жөнөтүү; Таймаут боюнча ажырым - экспоненциалдуу backoff + життер менен reconnect.
SSE: Server "комментарий" жиберет ':\n' heartbeat катары байланыш idle эсептелбейт; кардар өзү кайра кошулат.
4. 2 агымын калыбына келтирүү
WS: offset/sequence билдирүүлөрдү сактоо жана reconnect кийин дельта сурап.
SSE: колдонуңуз 'id:' ар бир окуя үчүн жана 'Last-Event-ID' өтүнүчүндө - сервер өткөрүп жиберилген окуяларды жөнөтөт.
5) Аутентификация жана авторизация
Сурам URL-жылы JWT Bearer (WS) коопсуз эмес (Логин агып). "Secure", "HttpOnly", "SameSite" желектери бар аталышты (баштапкы HTTP хэндшейк аркылуу) же кукилерди колдонуңуз.
mTLS (өзгөчө B2B үчүн), ошондой эле кол коюу (HMAC) баштапкы суроо-талаптын жогору болушу мүмкүн.
кукилер менен SSE үчүн CORS жөнүндө унутпа ('Access-Control-Allow-Origin', 'Allow-Credentials').
Токендин айланышы: агымды үзгүлтүккө учуратпаңыз. "Жакында бүтөт" → кардар жаңы токен менен байланышты кайра ачат.
6) Маалымат форматы жана компрессия
WebSocket: permessage-deflate этияттык менен күйгүзүү (CPU); кысылган форматтарды кысуудан качыңыз (Proto, Euro). JSON караганда экилик payload.
SSE: бул текст; ири маалыматтар үчүн REST/gRPC ресурстук же chunk-files шилтемени жөнөтүү; SSE үчүн транспорттук gzip - ылайыктуу, бирок прокси/CDN менен буферизацияга көз салуу.
7) Масштабдоо жана күйөрман
7. 1 Горизонталдуу масштабдоо
Тиркемени кайра баштоо үчүн иштебей калтырыңыз. Байланыштардын абалы - алдыңкы катмарда; маалыматтар - брокерден.
Sticky (session/user боюнча хэш) жергиликтүү кезек бар болсо керек.
Идеал - stateless фронт: түйүн гана жазылуу multiplexing; окуялар жалпы pub/sub келет.
7. 2 Pub/Sub жана брокерлер
Кеңири күйөрман үчүн Kafka/NATS/Redis Streams колдонуңуз.
"Fanout Gateway" катмары WS/SSE боюнча кардарларга топик жана пушит жазылат.
Ноддордун ортосундагы жүктү тең салмактоо үчүн багыттоо ачкычын (мисалы, 'userId', 'matchId') колдонуңуз.
8) Өндүрүш конфиги
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 (буферизацияны өчүрүү маанилүү)
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) Коддун мисалдары
9. 1 Кардар SSE (браузер)
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 (браузер)
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) Коопсуздук жана чектөө
Rate limiting per-connection жана per-user: кириш билдирүүлөр жыштыгын чектөө (WS) жана чыгыш агымы ылдамдыгы (WS/SSE).
Quota байланыштын жашоо убактысы жана жалпы трафик боюнча.
Message size limit и max messages/sec.
Хендшейк баскычында WAF/бот чыпкалар; connection flooding коргоо (кыска байланыштар көп).
tenant/namespace боюнча изоляция: ресурстардын өзүнчө бассейндери.
11) Байкоо
Метрикасы:- `connections_active`, `connections_new_total`, `bytes_in/out`,
- `messages_in/out_total`, `dropped_messages_total`,
- `reconnects_total`, `latency_delivery_ms{p50,p95,p99}`.
- Логи: IP/UA, userId/tenantId, жабуу себеби ('close _ code'), узактыгы.
- Trace: баштапкы команда менен окуяларды байланыштыруу (корреляциялык ID); WS үчүн "виртуалдык" спандарды батчаларда колдонуңуз.
12) Эксплуатациялык нюанстар
TLS Терминация кардарга жакын (CDN/edge).
Проактивдүү айлануу бирикмелери (graceful) деплойлор менен: "кайра туташтыруу" желегин бер.
"Ысык" каналдарды бирдей бөлүштүрүү үчүн ачкыч боюнча шардана.
Кийинки абоненттер үчүн абалдын сүрөттөрү (snapshot + delta).
Акыркы маанидеги кэш (өзгөчө SSE) - "муздак" кардар үчүн пайдалуу.
13) Анти-үлгүлөрү
WS аркылуу SSE же JSON аркылуу чоң бинардык бөлүктөрүн агымы - HTTP жүктөп алуу жана билдирүү шилтемени колдонуу.
Кошулган учурда гана авторизациялоо жана узакка созулган сессияларда кайра текшерүүлөрдүн жоктугу.
Global sticky кереги жок → дисбаланс жана "ысык" nodes.
Өчүрүлгөн таймауттар/лимиттер → илинген коннектилер бассейнди жейт.
SSE прокси/CDN → "реалдуу убакыт" буферизациясы кечигүү мүнөттөрүнө айланат.
Жок sequence/offset → кийин reconnect кардар маалыматтардын бүтүндүгүн жоготот.
14) Киргизүү чек-тизмеси
- Модель тандалган: WS (эки тараптуу) же SSE (бир тараптуу).
- орнотулган тайм, keepalive жана reconnect (backoff + Jitler).
- sequence/offset жана (SSE үчүн) 'id '/' Last-Event-ID' тарабынан иштелип чыккан.
- Аныкталган чектөөлөр: көлөмү/ылдамдыгы/байланыштар/квота, DoS коргоо.
- Proxy/Ingress: upgrade, off (SSE), read/send timeouts.
- Масштабдоо: pub/sub-брокер, күйөрман-чыгып, керек болсо гана sticky.
- Autentification: коопсуз токен берүү, үзүлүп жок айлануу.
- Байкоо: метрика, Логи, жолдор; дашборддор жана алерталар.
- Release планы: graceful-drain байланыштар, кайра туташуу жөнүндө кардар сигнал.
- Game Days: тармактын үзүлүшү, Nods кулашы, брокердин ашыкча жүктөө, узун RTT.
15) FAQ
CDN аркылуу SSE кэш болот?
Адатта жок: бул жекелештирилген агым. Коомдук каналдар үчүн - кыска TTL жана chunked-delivery менен болушу мүмкүн, бирок "реалдуу убакытты" бузуу оңой.
WebSocket HTTP/2/3 үстүндө иштейби?
Browser WS HTTP/1 башталат. 1-upgrade; h2 үчүн RFC 8441 бар, прокси/серверде колдоо өзүнчө талап кылынат. С h3 - кыймылда; h3 стриминг үчүн WebTransport бар, бирок бул башка API.
gRPC vs WS браузер үчүн?
Таза браузер gRPC сүйлөбөйт; gRPC-Web Envoy аркылуу керек. Интерактивдүү UI үчүн көбүнчө WS + REST оңой.
16) натыйжалары
WebSocket - реалдуу убакыт диалогу жана компакт эки тараптуу канал керек болгондо.
SSE - кардар үчүн жөнөкөй жана ишенимдүү push керек болгондо, минималдуу татаалдыгы жана автоматтык калыбына келтирүү.
Ийгилик - бул туура таймауттар жана лимиттер, offset, pub/sub-fan-out, туура прокси жөндөөлөрү жана так байкоо менен калыбына келтирүү.