Содержание
Для функций реального времени — чатов, уведомлений, живых статусов заказов — выбирают между тремя подходами. WebSocket нужен для двусторонней связи с частыми сообщениями, Server-Sent Events — когда данные идут только от сервера к клиенту, а периодический опрос сервера хорош для редких обновлений и самых простых случаев.
Разберём, чем отличаются эти подходы, как масштабировать открытые соединения и какие ошибки встречаются чаще всего.
Какие бывают способы обновлять данные в реальном времени?
Есть три основных способа: клиент регулярно спрашивает сервер (опрос), сервер держит открытый поток и отправляет события (SSE) или клиент и сервер держат двусторонний канал (WebSocket). Выбор зависит от того, кто инициирует сообщения и как часто они приходят.
| Подход | Направление | Когда подходит | Сложность |
|---|---|---|---|
| Опрос (polling) | Клиент спрашивает сервер | Обновления раз в десятки секунд, простые статусы | Низкая |
| Server-Sent Events | Сервер → клиент | Уведомления, ленты, прогресс задач, ответы AI | Средняя |
| WebSocket | В обе стороны | Чаты, совместное редактирование, игры, торговля | Выше |
Когда хватит обычного опроса сервера?
Опроса хватает, когда данные меняются редко, а задержка в 10–30 секунд никого не смущает: статус заявки, количество непрочитанных сообщений, состояние оплаты. Это самый простой вариант — работает через обычный API, кэш и балансировщик без доработок.
Минусы опроса проявляются на масштабе: тысячи клиентов, которые раз в несколько секунд спрашивают «есть ли новое», создают нагрузку, даже когда ничего не происходит. Как спроектировать такие запросы, мы разбирали в статье как спроектировать REST API.
Чем SSE отличается от WebSocket?
Server-Sent Events — это поток событий от сервера по обычному HTTP: браузер сам переподключается при обрыве, а настройка проще. WebSocket — отдельный протокол с двусторонним каналом: он нужен, когда клиент тоже часто отправляет данные и задержка должна быть минимальной.
// SSE: браузер сам переподключится при обрыве
const events = new EventSource('/api/orders/1842/stream')
events.addEventListener('status', (event) => {
const { status } = JSON.parse(event.data)
updateOrderStatus(status)
})
SSE отлично подходит для уведомлений, прогресса долгих задач и потоковых ответов языковых моделей. Для чата или совместного редактирования документа удобнее WebSocket.
Фото: Unsplash
Как масштабировать соединения?
Открытые соединения масштабируют отдельным сервером реального времени, а сообщения между экземплярами передают через брокер — например, Redis. Основное приложение публикует событие, сервер реального времени доставляет его всем подписанным клиентам, на каком бы экземпляре они ни были подключены.
Что учесть в архитектуре:
- Отдельный сервис для соединений. Долгие соединения не должны занимать процессы, которые обслуживают обычные запросы.
- Брокер сообщений. Через него экземпляры узнают о событиях друг друга — подробнее в статье Redis в веб-проекте.
- Каналы и авторизация. Пользователь подписывается только на свои каналы, а сервер проверяет права при подписке.
- Балансировщик. Он должен поддерживать долгие соединения и правильно их проксировать.
- Восстановление после обрыва. Клиент переподключается и запрашивает пропущенные события по последнему идентификатору.
Какие ошибки встречаются чаще всего?
Чаще всего ошибаются, когда считают канал реального времени надёжным хранилищем: соединение может оборваться в любой момент, и сообщение, отправленное в этот момент, потеряется. Источником правды должна оставаться база данных, а канал — только способом быстро сообщить об изменениях.
Типичные ошибки:
- нет повторной загрузки данных после переподключения — пользователь видит устаревшее состояние;
- рассылка всем подряд вместо персональных каналов и проверки прав;
- тяжёлая логика прямо в обработчике соединения вместо очереди;
- отсутствие ограничений на частоту сообщений от клиента;
- WebSocket там, где хватило бы опроса раз в 30 секунд.
Коротко
- Опрос подходит для редких обновлений, SSE — для потока от сервера, WebSocket — для двусторонней связи.
- SSE проще, работает по обычному HTTP и сам переподключается.
- Соединения держит отдельный сервис, события между экземплярами передаются через брокер.
- Канал реального времени — способ доставки, а не хранилище: после обрыва данные догружаются из API.
- Не усложняйте: начните с самого простого подхода, который решает задачу.
Частые вопросы
Можно ли сделать реальное время на PHP?
Да. Обычно PHP-приложение публикует события, а держит соединения отдельный сервер — например, Laravel Reverb, Centrifugo или облачный сервис. Сам код бизнес-логики остаётся привычным.
Сколько соединений выдержит один сервер?
Специализированный сервер на современном железе держит десятки и сотни тысяч открытых соединений. Ограничением чаще становятся частота сообщений и логика их рассылки, а не количество соединений.
Работают ли WebSocket в мобильных приложениях?
Работают, но только пока приложение открыто. Когда оно свёрнуто, соединение закрывается системой, поэтому важные события дублируют push-уведомлениями.



