WebSocket vs SSE vs Long Polling
WebSocket vs SSE vs Long Polling
Мы разобрали WebSocket'ы подробно. Но для real-time коммуникации есть и другие варианты — SSE и Long Polling. В этом уроке сравним все три подхода: когда что использовать, какие у каждого преимущества и недостатки.
Три подхода: краткий обзор
Long Polling — HTTP-запрос, который сервер не закрывает, пока нет данных. Когда данные появляются — ответ, и сразу новый запрос:
Клиент: GET /events?since=42
Сервер: ...ждёт 20 сек... 200 OK [данные]
Клиент: GET /events?since=43 (сразу же)
SSE (Server-Sent Events) — HTTP-соединение, открытое бесконечно. Сервер ПУШИТ данные клиенту в одностороннем порядке. Клиент не может отправлять данные обратно в том же соединении:
Клиент: GET /events (Accept: text/event-stream)
Сервер: 200 OK
data: {"price": 150.25}
data: {"price": 150.30}
...соединение открыто...
WebSocket — двусторонний канал. Обе стороны отправляют данные в любой момент:
Клиент: GET /chat (Upgrade: websocket)
Сервер: 101 Switching Protocols
Клиент ↔ Сервер: обмен сообщениями в обе стороны
Сравнительная таблица
| Характеристика | Long Polling | SSE | WebSocket |
|---|---|---|---|
| Направление | Клиент → Сервер → Клиент (оба) | Только Сервер → Клиент | Двустороннее |
| Протокол | HTTP | HTTP | WebSocket |
| Overhead | Полные HTTP-заголовки на каждое сообщение | HTTP-заголовки только при открытии | 2–10 байт на фрейм |
| Бинарные данные | Да (base64/бинарное тело) | Нет (только текст) | Да |
| Автопереподключение | Вручную | Встроено (EventSource) | Вручную |
| Прокси/файрволы | Отлично (обычный HTTP) | Отлично | Проблемы со старыми прокси |
| Поддержка iOS/Android WebView | Полная | Полная | Полная |
| Макс. соединений на домен | Нет (обычные запросы) | 6 (HTTP/1.1) | Нет лимита |
Когда использовать Long Polling
Long Polling — самая простая в реализации техника. Не требует специальной поддержки от сервера и работает через любой HTTP-прокси:
Плюсы:
- Работает везде, даже на старых браузерах и корпоративных прокси.
- Не требует выделенного WebSocket-сервера.
- Естественно решает проблему переподключения (каждый ответ — новый запрос).
Минусы:
- Высокий overhead (HTTP-заголовки на каждое событие).
- Задержка между ответом и новым запросом.
- Сервер держит много открытых TCP-соединений.
Long Polling сегодня — запасной вариант. Его используют, когда WebSocket и SSE недоступны (например, старые корпоративные прокси блокируют Upgrade-заголовки).
Когда использовать SSE
SSE (Server-Sent Events) — элегантное решение для одностороннего потока данных от сервера к клиенту. Браузерный API EventSource автоматически переподключается при разрыве:
const source = new EventSource('/api/events');
source.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Событие:', data);
};
source.addEventListener('price', (event) => {
// Именованное событие: event: price
updatePrice(JSON.parse(event.data));
});
Плюсы:
- Автоматическое переподключение с продолжением (через Last-Event-ID).
- Проще WebSocket'ов: обычный HTTP, не нужно настраивать прокси.
- Встроен в браузер:
EventSource.
Минусы:
- Только сервер → клиент. Для отправки данных серверу нужен отдельный HTTP-запрос.
- Только текст (бинарные данные нужно кодировать в base64).
- Ограничение в 6 соединений на домен (HTTP/1.1).
SSE идеален для: ленты новостей, push-уведомлений, биржевых котировок, логирования в реальном времени, прогресса операций.
Когда использовать WebSocket
WebSocket — полноценное двустороннее решение:
Плюсы:
- Двусторонняя связь с минимальным overhead.
- Бинарные данные нативно.
- Одно TCP-соединение для всего.
Минусы:
- Сложнее в настройке (нужен WebSocket-сервер, совместимость с прокси).
- Нет автопереподключения — нужно реализовывать самому.
- Избыточен, если нужен только поток от сервера к клиенту.
WebSocket нужен для: чатов, онлайн-игр, коллаборативного редактирования, видео/аудио сигнализации (хотя сам поток идёт через WebRTC, сигналы через WebSocket).
Гибридный подход: WebSocket с SSE-запасом
На практике часто используют WebSocket как основной транспорт и SSE через Long Polling как fallback. Библиотеки вроде Socket.IO делают это автоматически:
Попытка 1: WebSocket (wss://)
↓ не получилось (прокси блокирует)
Попытка 2: HTTP/2 SSE
↓ не получилось (старый браузер)
Попытка 3: HTTP/1.1 Long Polling
Для разработчика API библиотеки выглядит одинаково — детектирование транспорта происходит прозрачно.
Проверь себя
- В чём главное ограничение SSE по сравнению с WebSocket?
- Почему SSE может быть лучше WebSocket для push-уведомлений?
- Какую проблему решает гибридный подход с fallback?
- SSE — односторонняя связь (только сервер → клиент). Для отправки данных серверу нужен отдельный HTTP-запрос. WebSocket — двусторонний.
- Push-уведомления — это поток от сервера к клиенту. SSE проще (обычный HTTP, не нужно WebSocket-сервера), автоматически переподключается, не требует сложной логики переподключения.
- WebSocket может не работать через некоторые прокси и старые браузеры. Fallback на SSE/Long Polling гарантирует, что real-time будет работать у всех пользователей.
Что унести с урока
- Long Polling — самый простой, но накладной. Работает везде как запасной вариант.
- SSE — односторонний поток сервер → клиент, автопереподключение. Идеален для уведомлений, котировок, логов.
- WebSocket — двусторонний, минимальный overhead. Нужен для чатов, игр, коллаборативных приложений.
- Socket.IO и подобные библиотеки автоматически выбирают лучший доступный транспорт.
Модуль «WebSockets» завершён. Мы разобрали, как выйти за пределы request-response и построить real-time связь. В следующем модуле разберём безопасность в вебе — CORS, CSP, XSS, CSRF и токены.