Real-time: SSE и WebSockets
Оба механизма позволяют серверу отправлять данные клиенту в реальном времени.
WebSocket — двусторонний канал
const ws = new WebSocket('wss://example.com/ws');
ws.onopen = () => ws.send(JSON.stringify({ type: 'hello' }));
ws.onmessage = (e) => console.log(JSON.parse(e.data));
ws.onclose = () => console.log('disconnected');
ws.onerror = (e) => console.error(e);SSE — только сервер → клиент, через обычный HTTP
const es = new EventSource('/api/stream');
es.onmessage = (e) => console.log(e.data);
es.onerror = () => es.close();- Клиент открывает соединение, сервер держит его открытым и шлёт
data: ...\n\n - Формат:
text/event-stream - Автоматическое переподключение при обрыве (встроено в браузер)
- Только сервер → клиент (в отличие от WebSocket — двусторонний)
Когда использовать SSE: live-лента, нотификации, стриминг ответа от LLM (как ChatGPT).
SSE vs WebSocket
| SSE | WebSocket | |
|---|---|---|
| Направление | Только сервер→клиент | Двустороннее |
| Протокол | Обычный HTTP (stateless) | Отдельный протокол ws:// / wss:// (stateful) |
| Переподключение | Автоматически | Вручную |
| HTTP/2 | ✅ Работает, мультиплексирует | Классический handshake использует HTTP/1.1 Upgrade; поверх HTTP/2 возможен через RFC 8441, но поддержка не повсеместна |
| Аутентификация через Cookie | ✅ Автоматически, как обычный запрос | ⚠️ Сложнее, нет стандартных заголовков при апгрейде |
| Балансировщики/прокси | ✅ Прозрачно проходят | ⚠️ Часто требуют специальной настройки |
| Реализация на сервере | Проще | Сложнее |
| Использование | Уведомления, лента, стриминг | Чат, игры, биржа |
Если нужна только подписка на обновления — SSE проще и работает через обычный HTTP без смены протокола.
См. также
- rest-graphql — GraphQL subscriptions через WebSocket
- http-history — HTTP/2 и мультиплексирование
- js-objects-async — промисы и async