Long polling и SSE
↑ 5.4 Работа с API: REST, GraphQL, WebSocket · ← Предыдущая · → Следующая
Зачем это на собесе
Более простые альтернативы WebSocket для односторонних обновлений.
Объяснение
| Технология | Как работает | Направление | Особенности |
|---|---|---|---|
| Short polling | запрос по таймеру | клиент → сервер | просто, лишняя нагрузка и задержка |
| Long polling | запрос висит, пока не появятся данные или таймаут, затем сразу новый | клиент → сервер | работает везде; нагрузка на соединения |
| SSE (Server-Sent Events) | постоянное HTTP-соединение, сервер шлёт text/event-stream | сервер → клиент | авто-переподключение, Last-Event-ID, только текст, HTTP/2 мультиплексирование |
| WebSocket | двусторонний канал | оба | бинарные данные, свой протокол |
// SSE
const es = new EventSource("/api/orders/stream", { withCredentials: true });
es.addEventListener("order-updated", (e) => handle(JSON.parse((e as MessageEvent).data)));
es.onerror = () => { /* браузер сам переподключается; es.readyState */ };
es.close();Формат потока:
id: 42
event: order-updated
data: {"id":1,"status":"paid"}
retry: 5000Ограничения EventSource: только GET, нельзя задать заголовки (аутентификация через cookie/query), ограничение ~6 соединений на домен в HTTP/1.1. Для POST/заголовков — fetch + чтение потока (@microsoft/fetch-event-source).
// Long polling
async function poll(signal: AbortSignal, since = 0) {
while (!signal.aborted) {
try { const r = await fetch(`/api/events?since=${since}`, { signal }); if (r.status === 200) { const { events, cursor } = await r.json(); events.forEach(handle); since = cursor; } }
catch { await sleep(2000); } // backoff при ошибке
}
}Выбор: уведомления, прогресс задач, ленты — SSE; чат, игры, совместное редактирование — WebSocket; окружение без поддержки — long polling. Через прокси убедитесь, что не буферизуется ответ (X-Accel-Buffering: no).
Нюансы и подводные камни
- Прокси/CDN могут буферизовать SSE и ломать поток.
- Потерянные события: используйте
idиLast-Event-IDдля догоняющей отправки. - Закрывайте
EventSourceпри размонтировании. - Много вкладок × много соединений — лимиты.
- Безопасность: авторизация по cookie и проверка origin.
Практика
- Реализуйте прогресс фоновой задачи через SSE.
- Сравните нагрузку short polling, long polling и SSE.
- Добавьте
Last-Event-IDи повторное подключение.
Вопросы с ответами
SSE или WebSocket?
SSE — односторонний поток от сервера, проще и с авто-переподключением; WebSocket — двусторонний обмен, бинарные данные.
Как работает long polling?
Клиент отправляет запрос, сервер держит его до появления данных или таймаута, после ответа клиент сразу отправляет новый.