SSE
SSE (от англ. Server-Sent Events, «события, отправляемые сервером») — это технология веб-разработки, позволяющая серверу асинхронно отправлять данные клиенту (веб-браузеру или другому HTTP-клиенту) через одно долгоживущее HTTP-соединение. SSE является частью стандарта HTML5 и реализует однонаправленный поток данных от сервера к клиенту, в отличие от двунаправленного протокола WebSocket. Технология используется для передачи уведомлений, обновлений ленты новостей, котировок акций, метрик мониторинга и других событий в реальном времени.
История
Концепция отправки сервером данных без явного запроса клиента существовала с ранних дней веба, но была реализована через различные нестандартные механизмы (например, длинные опросы, long polling, или скрытые iframe). В 2006 году компания Opera Software предложила спецификацию Server-Sent Events в рамках работы над стандартом HTML5. В 2009 году спецификация была включена в черновик HTML5, а в 2014 году стала частью финальной рекомендации W3C (World Wide Web Consortium). Первоначально поддержка SSE была ограничена браузерами, но к середине 2010-х годов все основные современные браузеры (кроме Internet Explorer) добавили поддержку API EventSource. В России технология начала активно применяться с развитием SPA-приложений (Single Page Application) и сервисов реального времени, таких как онлайн-биржи, панели мониторинга и системы оповещения.
Принцип работы
SSE использует стандартный протокол HTTP. Клиент инициирует соединение, отправляя запрос GET с заголовком Accept: text/event-stream. Сервер, получив такой запрос, устанавливает долгоживущее соединение и начинает отправлять данные в формате text/event-stream. Соединение остаётся открытым, пока сервер или клиент не прервут его. В отличие от WebSocket, SSE не требует специального протокола рукопожатия (handshake) — используется обычный HTTP, что упрощает интеграцию с существующей инфраструктурой (прокси, балансировщики нагрузки, межсетевые экраны).
Формат данных
Данные передаются в виде текстовых сообщений, каждое из которых состоит из полей, разделённых символами новой строки. Основные поля:
event:— тип события (строка). Если не указано, генерируется событиеmessage.data:— тело сообщения (может быть многострочным, каждая строка начинается сdata:).id:— идентификатор последнего события. Используется для восстановления соединения после разрыва.retry:— время в миллисекундах, через которое клиент должен попытаться переподключиться при разрыве соединения.
Пример потока:
`` event: update data: {"temperature": 22.5, "humidity": 60} id: 12345 retry: 3000 ``
Каждое сообщение должно заканчиваться двумя символами новой строки (\n\n).
API EventSource
На стороне клиента (браузера) SSE реализуется через объект EventSource, входящий в стандартный JavaScript API. Синтаксис:
``javascript const source = new EventSource('/events'); source.addEventListener('message', function(event) { console.log('Получено сообщение:', event.data); }); source.addEventListener('update', function(event) { console.log('Событие update:', event.data); }); ``
Объект EventSource автоматически обрабатывает переподключение при разрыве соединения, используя поле id для передачи последнего полученного идентификатора серверу. Это позволяет избежать потери данных.
Отличия от других технологий
SSE и WebSocket
- Направленность: SSE — однонаправленный (сервер → клиент); WebSocket — двунаправленный (полный дуплекс).
- Протокол: SSE — поверх HTTP; WebSocket — собственный протокол (ws:// или wss://), требующий обновления соединения (upgrade).
- Поддержка: SSE поддерживается всеми современными браузерами (кроме Internet Explorer); WebSocket — также широко поддерживается, но требует более сложной настройки серверной инфраструктуры.
- Автоматическое переподключение: SSE имеет встроенный механизм переподключения; WebSocket требует реализации на стороне клиента.
- Бинарные данные: SSE передаёт только текст (обычно JSON или строки); WebSocket поддерживает бинарные данные (Blob, ArrayBuffer).
SSE и Long Polling
- Задержка: SSE обеспечивает меньшую задержку, так как соединение постоянно открыто; Long Polling требует повторных HTTP-запросов при каждом обновлении.
- Нагрузка: SSE создаёт меньше нагрузки на сервер и сеть, так как не требует частых установок и разрывов соединений.
- Сложность: Long Polling проще в реализации на серверах, не поддерживающих SSE, но менее эффективен.
Применение
SSE широко используется в сценариях, где требуется передача обновлений от сервера к клиенту в реальном времени, но не требуется двусторонняя связь. Основные области применения:
- Финансовые данные: передача котировок акций, курсов валют, криптовалют.
- Мониторинг и логирование: отображение метрик серверов, логов приложений, статусов устройств в дашбордах.
- Социальные сети и новости: уведомления о новых сообщениях, лайках, комментариях, обновлениях ленты.
- Онлайн-игры: передача состояния игрового поля, изменений рейтинга, уведомлений о событиях.
- Системы оповещения: рассылка экстренных сообщений, уведомлений о сбоях, изменениях в расписании.
- Интернет вещей (IoT): передача показаний датчиков, статусов устройств.
В России SSE применяется в таких проектах, как биржевые терминалы (например, Московская биржа), панели мониторинга «Яндекс.Метрики», системы уведомлений в социальных сетях и мессенджерах.
Ограничения и недостатки
- Однонаправленность: SSE не позволяет клиенту отправлять данные серверу через то же соединение. Для отправки данных клиент должен использовать отдельные HTTP-запросы (например, через Fetch API).
- Максимальное количество соединений: Браузеры ограничивают количество одновременных SSE-соединений с одного домена (обычно 6–8). Это может быть проблемой для приложений, требующих множества параллельных потоков.
- Поддержка в старых браузерах: Internet Explorer и некоторые мобильные браузеры не поддерживают SSE. Для них требуется полифилл (например, на основе Long Polling).
- Прокси и балансировщики: Некоторые HTTP-прокси и балансировщики нагрузки могут разрывать долгоживущие соединения, если они не настроены соответствующим образом. Требуется настройка тайм-аутов и поддержка keep-alive.
- Безопасность: SSE-соединения подвержены тем же атакам, что и обычные HTTP-запросы (CSRF, XSS). Для защиты рекомендуется использовать HTTPS, проверку токенов аутентификации и заголовки CORS.
Реализация на серверной стороне
SSE может быть реализован на любом серверном языке, поддерживающем работу с HTTP-соединениями. Примеры:
- Node.js: библиотека
express-sseили ручная реализация черезres.writeHead(200, {'Content-Type': 'text/event-stream'}). - Python: фреймворки Flask, Django, FastAPI (через
StreamingResponse). - Java: сервлеты с поддержкой асинхронной обработки (AsyncContext) или Spring WebFlux.
- PHP: скрипты, работающие в режиме реального времени (требуется отключение буферизации вывода).
- C#: ASP.NET Core с поддержкой Server-Sent Events.
Интересные факты
- Технология SSE была впервые реализована в браузере Opera 9.0 в 2006 году.
- Несмотря на название, SSE не является частью спецификации «Server-Sent Events» как отдельного стандарта — она входит в состав HTML5.
- SSE может использоваться вместе с WebSocket в одном приложении: WebSocket — для двустороннего обмена, SSE — для массовых рассылок.
- В 2019 году компания Cloudflare запустила поддержку SSE через свою сеть доставки контента (CDN), что упростило масштабирование приложений реального времени.
Источники
- W3C Recommendation: Server-Sent Events (HTML5)
- MDN Web Docs: Server-Sent Events
- Статья «Server-Sent Events: The Simple Way to Real-Time Web» на сайте HTML5 Rocks
- Документация библиотеки
express-sseдля Node.js - Статья «Real-Time Web Applications with Server-Sent Events» на сайте Toptal
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →