WebSockets против SSE против Long Polling — реальное время без паники

Обновлено

WebSockets, SSE и долгий запрос каждый имеет свое место. Вот в каких случаях использовать каждый из них — с таблицей сравнения, примерами кода и руководством по выбору.

WebSockets против SSE против долгого опроса — Реальное время без паники 1
Реклама · УДАЛИТЬ?

Большинство разработчиков по умолчанию выбирают WebSockets. Обычно это ошибочно.

Не потому что WebSockets плохие — они отлично справляются со своей задачей. Но они несут реальные расходы на инфраструктуру: стабильные сессии на балансировщиках нагрузки, специальная логика для сердечников, обходы аутентификации и настройка прокси, которая работает нормально, пока кто-то не открывает ваше приложение в корпоративной сети. Для большинства «реальных» требований к времени реагирования эти расходы не оправданы.

Кратко: если данные передаются только с сервера на клиент, используйте Server-Sent Events (SSE). Если клиент должен отправлять данные обратно с низкой задержкой, используйте WebSockets. Если частота обновления измеряется в секундах и вы хотите самую простую возможную развертку, долгое опросирование по-прежнему работает — и в этом нет ничего неправильного.

Сравнение

ТехникаНаправлениеПоддержка в браузерахАвтоматическое восстановление соединенияСложность балансировщика нагрузкиИ ни один из вариантов не является универсально лучшим. JWT отлично справляется с аутентификацией без состояния в нескольких сервисах. Токены сессий проще, когда вы контролируете всю структуру и нуждаетесь в мгновенной отмене (например, «выход во всех приложениях» в случае безопасности).
Долгое опрослениеСервер → КлиентУниверсальныйРучное (клиент пересылает запросы)Нет (стандартный HTTP)Низкая частота обновлений, интервалы ≥15 секунд
SSEСервер → КлиентВсе современные (не IE11)Встроена (EventSource)Нет (стандартный HTTP)Живые потоки, уведомления, дашборды
WebSocketsДвунаправленныйВсе современныеРучное (создание сердечника)Требует стабильных сессийЧат, игры, совместное редактирование

Долгое опросление

Долгое опросление — это стандартное опросление HTTP, при котором сервер держит запрос открытым до тех пор, пока не будет доступна информация, или сработает таймаут. Клиент отправляет запрос, сервер ждёт, возвращает ответ при наличии данных и сразу же запускает следующий запрос. Это цикл, маскированный под сеть.

Это действительно подходит для широкого круга случаев:

  • Иконки уведомлений — количество непрочитанных сообщений, обновляющихся каждые 30 секунд, не требует постоянного соединения.
  • Дашборды для администраторов с ослабленной свежестью данных — метрики, обновляющиеся каждые 15–60 секунд, работают хорошо при опросе.
  • Мобильные приложения на нестабильных соединениях — постоянные соединения уничтожаются агрессивным управлением сетью; опрос восстанавливается чисто при каждом запросе.
  • За корпоративными прокси-серверами — многие корпоративные прокси-серверы буферизируют или прерывают нестандартные соединения. Опрос HTTP работает повсюду, без исключений.

Ограничение масштаба действительно существует. Каждый открытый запрос занимает место соединения. На серверах с потоками это становится дорогостоящим; на серверах с циклическим исполнением (Node.js, Tornado, Go с goroutines) это умеренно, но не бесплатно. При десятках тысяч одновременных пользователей математика по ресурсам сервера начинает играть роль.

Server-Sent Events (SSE)

SSE — это вариант, который большинство разработчиков пропускают, направляясь к WebSockets. Это ошибка для любого случая, где данные идут в одну сторону: с сервера на клиента.

Он работает над стандартным HTTP. Сервер устанавливает Content-Type: text/event-stream и записывает сообщения, разделённые символом новой строки, в тело ответа бесконечно. В браузере встроенная EventSource API автоматически обрабатывает переподключение — включая Last-Event-ID заголовок, чтобы сервер мог возобновить поток после потери соединения. Вы получаете именованные типы событий, настраиваемые интервалы повтора и не требуется никакой библиотеки.

const source = new EventSource('/api/events');

source.addEventListener('priceUpdate', (e) => {
  const { price, symbol } = JSON.parse(e.data);
  updateTicker(symbol, price);
});

source.onerror = () => {
  // EventSource reconnects automatically — nothing to do here
};

Что SSE делает правильно:

  • Стандартный HTTP — работает через балансировщики нагрузки, обратные прокси и CDN без настройки. Без стабильных сессий.
  • Автоматическое восстановление соединения — встроено в спецификацию. Установите retry: поле в потоке для настройки интервала; клиент сам управляет остальным.
  • Мультиплексирование HTTP/2 — устраняет старое ограничение в 6 соединений на домен в HTTP/1.1. Если вы используете HTTP/2 (вы должны использовать), это не является проблемой.
  • Упрощённая реализация на сервере — поддерживайте открытое соединение и записывайте в него. Не требуется протокол, не требуется разбор кадров, не требуется логика сердечников.

Одна реальная ограничение: SSE односторонний. Клиент не может отправлять данные через соединение SSE. На практике это редко является проблемой — используйте обычные POST-запросы для любых данных, которые клиент должен отправить, вместе с потоком SSE для событий сервера. Оба работают без проблем.

Значимо знать ограничение HTTP/1.1. Браузеры ограничивают количество одновременных соединений на домен в рамках всех вкладок на 6. Три вкладки браузера, каждая из которых использует два потока SSE, достигают предела. HTTP/2 устраняет это за счёт мультиплексирования. Если вы не можете гарантировать доставку HTTP/2 (некоторые старые конфигурации CDN, некоторые корпоративные прокси), помните об этом.

WebSockets

WebSockets — правильный инструмент, когда действительно требуется двусторонняя, низкозадержка передача данных. Случаи, которые оправдывают сложность:

  • Чат — сообщения от каждого пользователя должны достигать других почти в реальном времени. WebSockets — стандарт здесь, и это имеет причину.
  • Мультиплейерные игры — состояние игры синхронизируется между клиентами постоянно, часто с частотой от 20 до 60 обновлений в секунду. Никакой другой подход не приближается к такой эффективности на уровне кадров.
  • Совместное редактирование — реальное редактирование на основе CRDT или OT (Notion, Figma, Google Docs-стиль) требует, чтобы каждый ввод был передан с минимальной задержкой.
  • Торговые терминалы — потоки цен с задержкой менее 100 мс с подачей заказов на том же соединении. WebSockets были созданы для этого.

Инфраструктурные расходы, которые избегают SSE и опрос:

  • Стабильные сессии — соединения WebSocket являются состоятельными и привязанными к одному процессу сервера. Балансировщики нагрузки требуют сессионной привязки (по IP или на основе куки), чтобы правильно перенаправлять переподключения. Без этого переподключившийся клиент может попасть на сервер, который не знает о его сессии.
  • Настройка прокси и CDN — Nginx, HAProxy и Cloudflare поддерживают WebSockets, но требуют явной настройки (Upgrade и Connection заголовки, proxy_http_version 1.1 в Nginx). Некоторые корпоративные экраны блокируют 101 Switching Protocols. Вы узнаете об этом в поддержке от пользователей в конкретных офисах.
  • Сложность аутентификации — WebSockets не могут устанавливать пользовательские заголовки после первичного рукопожатия. Аутентификация по токену обычно означает передачу токена в строку запроса (неудобно, распространено) или в первое сообщение после подключения (лучше, но требует серверной логики фильтрации).
  • Сердечники — спецификация не требует поддержки сердечников. Без специальной логики ping/pong вы не обнаружите умерших соединений до тех пор, пока не пропадёт следующее сообщение. Либо реализуйте сердечники, либо принимайте устаревшие соединения без реакции.

Никакие из этих факторов не являются барьерами — они решаемы. Они представляют собой сложность, которая не существует при использовании SSE или опроса. Если вы выбираете WebSockets для потока уведомлений или дашборда в реальном времени, вы платите за это без причины.

Как выбрать

Рассмотрите эти пункты по порядку:

  1. Нужно ли клиенту отправлять данные на сервер с высокой частотой, или важна задержка менее 200 мс? Нет → пропустите WebSockets.
  2. Только ли данные идут с сервера на клиента? Да → SSE почти наверняка является правильным выбором.
  3. Вы на HTTP/2? Если да, SSE не имеет значимых ограничений для большинства случаев. Если нет, учитывайте ограничение в 6 соединений.
  4. Ваша развертка — серверная или находится за инфраструктурой, не поддерживающей постоянные соединения? SSE работает на большинстве серверных платформ (Vercel, Cloudflare Workers через API Streams); WebSockets на серверной платформе требуют дополнительной инфраструктуры.
  5. Частота обновления составляет 15 секунд или больше? Долгое опросление. Оставайтесь простыми.

Если вы прошли через этот процесс и ответ всё ещё WebSockets — хорошо. Теперь вы используете их для правильной причины, а не по умолчанию.

Отладка потоков событий

SSE data: Поля и сообщения WebSocket почти всегда содержат JSON. При отладке неисправного потока самым быстрым способом является вставка сырого заголовка в IO Tools’ JSON Formatter для быстрого просмотра структуры — особенно для вложенных объектов событий, где отсутствующий скобка или лишняя запятая убивает парсинг безусловно.

Хотите убрать рекламу? Откажитесь от рекламы сегодня

Установите наши расширения

Добавьте инструменты ввода-вывода в свой любимый браузер для мгновенного доступа и более быстрого поиска

в Расширение Chrome в Расширение края в Расширение Firefox в Расширение Opera

Табло результатов прибыло!

Табло результатов — это интересный способ следить за вашими играми, все данные хранятся в вашем браузере. Скоро появятся новые функции!

Реклама · УДАЛИТЬ?
Реклама · УДАЛИТЬ?
Реклама · УДАЛИТЬ?

новости с техническими моментами

Примите участие

Помогите нам продолжать предоставлять ценные бесплатные инструменты

Купи мне кофе
Реклама · УДАЛИТЬ?