Long polling и SSE

↑ 5.4 Работа с API: REST, GraphQL, WebSocket · ← Предыдущая · → Следующая

Обязательно~3 мин чтенияУровень: middle

Зачем это на собесе

Более простые альтернативы 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.

Практика

  1. Реализуйте прогресс фоновой задачи через SSE.
  2. Сравните нагрузку short polling, long polling и SSE.
  3. Добавьте Last-Event-ID и повторное подключение.

Вопросы с ответами

Связанные темы