WebSocket (клиент)
Полнодуплексный канал поверх TCP: сервер пушит сообщения клиенту в реальном времени.
Что это
HTTP-запрос с Upgrade: websocket превращает соединение в постоянный двунаправленный канал. В отличие от long-polling — экономно по трафику; в отличие от Server-Sent Events — двунаправленно и поддерживает бинарные данные.
Базовое использование
const ws = new WebSocket('wss://api.example.com/sync');
ws.addEventListener('open', () => {
console.log('connected');
ws.send(JSON.stringify({ type: 'subscribe', topic: 'rooms' }));
});
ws.addEventListener('message', (event) => {
// event.data — string | Blob | ArrayBuffer
const msg = JSON.parse(event.data);
console.log(msg);
});
ws.addEventListener('close', (event) => {
console.log('closed', event.code, event.reason);
// переподключиться с экспоненциальным backoff
});
ws.addEventListener('error', (e) => console.error(e));
// Отправка
ws.send('text');
ws.send(JSON.stringify({ a: 1 }));
ws.send(new Uint8Array([1, 2, 3])); // бинарь
// Закрыть
ws.close(1000, 'bye');
Состояния
readyState |
Что |
|---|---|
0 CONNECTING |
Открывается |
1 OPEN |
Готов слать/принимать |
2 CLOSING |
Закрывается |
3 CLOSED |
Закрыт |
Reconnect-обёртка (минимум)
function connect(url, onMessage) {
let ws;
let attempt = 0;
const open = () => {
ws = new WebSocket(url);
ws.onopen = () => { attempt = 0; };
ws.onmessage = (e) => onMessage(JSON.parse(e.data));
ws.onclose = () => {
const delay = Math.min(1000 * 2 ** attempt++, 30_000);
setTimeout(open, delay);
};
};
open;
return => ws.close();
}
Поддержка
Везде. ws:// (plaintext) и wss:// (TLS — на проде ОБЯЗАТЕЛЬНО).
Подводные камни
- На фоне в браузере может уснуть (Chrome не закрывает, но throttles)
- Нет встроенного reconnect — пиши сам
- Нет встроенного ping/pong доступного из JS — heartbeat руками (отправляй пустое сообщение раз в N секунд)
- Через прокси/корпоративные firewall'ы
wss://иногда блокируется - Не путать с Socket.IO (это библиотека поверх WS с fallback'ами)
- Заголовки кастомные в
WebSocketctor нельзя установить (только subprotocol через 2-й аргумент)
Альтернативы
| Когда | |
|---|---|
| WebSocket | Bi-directional real-time |
SSE (EventSource) |
Только сервер→клиент, через HTTP |
| WebTransport | HTTP/3, новее, не везде |
| WebRTC DataChannel | P2P между браузерами |
Используется в bootcamp
- Любая real-time задача — чаты, live-обновления, синхронизация
- В local-first архитектуре (Метархия) — единственный канал между Service Worker и сервером
Ссылки
🎓 Источники
- 🎓 WebSocket сервер на Node.js (электронные таблицы и чат) · TimurShemsedinov · 2018-10-31
- 🎓 🔀 Фронтендеры не знают Web API · TimurShemsedinov · 2025-12-10
- Не открывать 100 WebSocket-ов на клиенте — один общий внутри Service Worker.
- ⚡ Service Worker для PWA приложений · AsForJS · 2026-01-26
- Один WebSocket в SW обслуживает все вкладки.