Server-Sent Events, Polling и Long Polling: что это и когда использовать
Что это вообще?
Все три технологии — способы получения данных с сервера в браузере. Они позволяют обновлять клиент в реальном или почти реальном времени, особенно при отсутствии WebSockets.
Polling (Обычный опрос)
Клиент периодически опрашивает сервер: «Есть что-то новенькое?»
Как работает polling:
- Клиент отправляет
GET /data
- Сервер немедленно отвечает (даже если ничего не изменилось)
- Через X секунд клиент снова отправляет запрос
setInterval(() => {
fetch('/data')
.then(res => res.json())
.then(data => console.log(data));
}, 5000); // Запрос каждые 5 сек
Минусы polling
- Постоянная нагрузка на сервер (много "пустых" запросов)
- Данные приходят с задержкой
- Плохая масштабируемость
Long Polling (Длинный опрос)
Улучшенная версия обычного polling'а: запрос живёт до появления новых данных.
Как работает long polling:
- Клиент делает запрос
- Сервер ждёт появления данных (или истечения тайм-аута)
- Отдаёт данные → клиент сразу отправляет следующий запрос
function longPolling() {
fetch('/data')
.then(res => res.json())
.then(data => {
console.log(data);
longPolling(); // Цикл продолжается
});
}
longPolling();
Плюсы long polling
- Меньше "пустых" запросов
- Данные приходят почти мгновенно
- Не требует новой технологии (работает по обычному HTTP)
Минусы long polling
- Данные приходят с задержкой
- Плохая масштабируемость
Server-Sent Events (SSE)
SSE — это постоянное соединение, по которому сервер отправляет данные клиенту, когда захочет.
Это однонаправленное соединение: только сервер → клиент
Как работает SSE
- Клиент создаёт
EventSource
- Сервер устанавливает
text/event-stream
- Сервер может отправлять сообщения без запроса от клиента
Пример (Клиент)
const eventSource = new EventSource('/events');
eventSource.onmessage = (event) => {
console.log("Новое сообщение:", event.data);
};
Пример (Сервер на Express)
app.get('/events', (req, res) => {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
setInterval(() => {
res.write(`data: ${JSON.stringify({ time: new Date() })}\n\n`);
}, 3000);
});
Преимущества SSE
- Простая реализация
- Работает по одному соединению
- Идеально для уведомлений, чатов, стриминга данных
- Работает даже через прокси (поддерживает HTTP/2)
Сравнение
Метод | Направление | Постоянное соединение | Мгновенность | Сложность | Поддержка |
---|---|---|---|---|---|
Polling | Client → Server | Нет | Нет | Простая | Все |
Long Polling | Client → Server | Временно | Почти | Средняя | Все |
SSE | Server → Client | Да | Да | Средняя | Почти все (кроме IE) |
Что выбрать?
- Polling: если нет возможности использовать другие методы или это не критично (например, обновление раз в 30 сек)
- Long Polling: если данные должны приходить сразу, но вы не можете использовать SSE или WebSocket
- SSE: для однонаправленного real-time (чаты, уведомления, ленты новостей)
- WebSocket: для двусторонней связи — игры, коллаборативные редакторы, видеочаты, чаты, и т.д.
Вывод:
Polling — это просто, но неэффективно. Long Polling — компромисс. SSE — отличное решение для real-time без использования WebSocket. Выбор зависит от направления связи, нагрузки, требований к latency и браузерной поддержки.