Открыть сервис

Server-Sent Events

Server-Sent Events (SSE) — это технология, позволяющая веб-серверу отправлять клиенту (обычно веб-браузеру) потоковые уведомления или обновления данных в реальном времени через одно долгоживущее HTTP-соединение. SSE является частью стандарта HTML5 и специфицируется в рекомендации W3C «Server-Sent Events». В отличие от WebSocket, SSE обеспечивает однонаправленную передачу данных от сервера к клиенту, что упрощает реализацию для сценариев, где клиенту не требуется отправлять данные обратно.

История

Концепция Server-Sent Events была предложена Яном Хиксоном (Ian Hickson) в 2004 году в рамках работы над спецификацией HTML5. Первоначально технология называлась «DOM Events» и предназначалась для упрощения создания веб-приложений с функциями «push-уведомлений». В 2009 году спецификация SSE была выделена в отдельный документ, а в 2014 году стала частью рекомендации W3C «HTML5».

Первые реализации SSE появились в браузерах Opera (2006 год) и Firefox (2007 год). Поддержка в Internet Explorer отсутствовала вплоть до прекращения его поддержки корпорацией Microsoft, что долгое время сдерживало массовое внедрение технологии. В 2018 году SSE была включена в стандарт WHATWG HTML Living Standard.

Принцип работы

SSE использует стандартный протокол HTTP. Клиент инициирует соединение, отправляя запрос с заголовком Accept: text/event-stream. Сервер в ответе устанавливает заголовок Content-Type: text/event-stream и поддерживает соединение открытым, периодически отправляя текстовые сообщения в определённом формате.

Формат данных

Сообщения SSE представляют собой текстовые строки, начинающиеся с ключевых полей:

  • event: — тип события (необязательно, по умолчанию message);
  • data: — содержимое события (обязательно, может быть многострочным);
  • id: — идентификатор последнего события (используется для восстановления после разрыва соединения);
  • retry: — время в миллисекундах, через которое клиент должен попытаться переподключиться после разрыва.

Каждое событие завершается двумя символами перевода строки (\n\n). Пример сообщения: ``` event: update data: {"temperature": 22.5} id: 42

```

Установка соединения

Клиент создаёт объект EventSource в JavaScript, передавая URL конечной точки сервера: ``javascript const source = new EventSource('/events'); source.addEventListener('update', function(event) { console.log('Получено обновление:', event.data); }); ` Сервер, в свою очередь, должен поддерживать соединение открытым, не закрывая его после отправки данных. В случае разрыва соединения (например, из-за сетевой ошибки) браузер автоматически пытается переподключиться, используя последний полученный id`, если он был передан.

Отличия от WebSocket и Long Polling

SSE занимает промежуточное положение между традиционными методами опроса сервера (Long Polling) и двунаправленным протоколом WebSocket.

ХарактеристикаSSEWebSocketLong Polling
НаправлениеОднонаправленное (сервер → клиент)ДвунаправленноеОднонаправленное (имитация)
ПротоколHTTPСобственный (ws://)HTTP
Автоматическое переподключениеВстроено в браузерТребует реализацииТребует реализации
Поддержка в браузерахВсе современные, кроме IEВсе современныеВсе
Максимальное количество соединений6-8 на домен (ограничение браузера)Не ограничено (но ограничено системой)Зависит от реализации
Сложность реализацииНизкаяСредняяСредняя

SSE проще в реализации, чем WebSocket, так как использует стандартный HTTP и не требует дополнительных библиотек на стороне клиента. Однако SSE не поддерживает отправку данных от клиента к серверу, что делает его непригодным для интерактивных приложений (например, онлайн-игр или чатов).

Применение

SSE используется в сценариях, где требуется односторонняя передача данных от сервера к клиенту в реальном времени:

  • Уведомления и оповещения: системы мониторинга, социальные сети, новостные ленты.
  • Обновление данных в реальном времени: биржевые котировки, спортивные результаты, погода.
  • Потоковая передача логов: консоли управления, системы CI/CD.
  • Интернет вещей (IoT): передача показаний датчиков на веб-интерфейс.
  • Совместная работа: синхронизация состояния документов (например, в Google Docs — хотя там используется комбинация технологий).

Примеры в российской практике

  • В сервисе «Яндекс.Почта» SSE используется для отображения уведомлений о новых письмах без перезагрузки страницы.
  • На платформе «Госуслуги» SSE применяется для обновления статуса заявлений и уведомлений пользователя.
  • В системах мониторинга «Ростелекома» SSE используется для отображения состояния сетевого оборудования в реальном времени.

Ограничения и проблемы

  1. Ограничение на количество соединений: браузеры обычно ограничивают количество одновременных SSE-соединений на один домен (6-8 в зависимости от реализации). Для обхода этого ограничения можно использовать поддомены или WebSocket.
  2. Отсутствие поддержки в Internet Explorer: SSE не поддерживается в IE, что может быть критично для корпоративных приложений.
  3. Проблемы с прокси-серверами: некоторые прокси-серверы и балансировщики нагрузки могут буферизировать ответы, что нарушает потоковую передачу. Требуется настройка X-Accel-Buffering: no (для nginx) или аналогичных параметров.
  4. Отсутствие двунаправленной связи: для отправки данных от клиента серверу необходимо использовать дополнительные HTTP-запросы (например, AJAX).
  5. Работа через HTTP/2: SSE может конфликтовать с мультиплексированием HTTP/2, так как каждое SSE-соединение занимает отдельный поток. Рекомендуется использовать HTTP/1.1 для SSE.

Безопасность

SSE, как и любой другой механизм передачи данных, подвержен ряду угроз:

  • Cross-Origin Resource Sharing (CORS): SSE-соединения подчиняются политике CORS. Сервер должен явно разрешать кросс-доменные запросы с помощью заголовка Access-Control-Allow-Origin.
  • Инъекция данных: злоумышленник может попытаться внедрить вредоносные данные в поток SSE. Рекомендуется использовать HTTPS и проверять целостность данных на стороне клиента.
  • Отказ в обслуживании (DoS): злоумышленник может открыть множество SSE-соединений, исчерпав ресурсы сервера. Сервер должен ограничивать количество соединений от одного клиента.

Реализация на серверной стороне

SSE может быть реализован на любом языке программирования, поддерживающем работу с HTTP. Пример на Python с использованием фреймворка Flask:

```python from flask import Flask, Response, stream_with_context import time

app = Flask(__name__)

@app.route('/events') def stream(): def generate(): while True: yield f"data: {time.time()}\n\n" time.sleep(1) return Response(stream_with_context(generate()), mimetype='text/event-stream')

if __name__ == '__main__': app.run(threaded=True) ```

Аналогичные реализации существуют для Node.js (Express), Java (Spring), PHP, Go и других языков.

Будущее технологии

Несмотря на конкуренцию со стороны WebSocket, SSE остаётся востребованной технологией для простых сценариев push-уведомлений. В 2023 году в спецификацию HTML Living Standard были добавлены улучшения, касающиеся работы SSE с Service Workers, что позволяет получать уведомления даже при закрытом окне браузера. Также ведутся работы по интеграции SSE с протоколом HTTP/3 (QUIC), что может повысить производительность потоковой передачи данных.

Источники

  1. W3C Recommendation «Server-Sent Events» (2014).
  2. WHATWG HTML Living Standard — «Server-sent events» (2024).
  3. MDN Web Docs — «Using server-sent events».
  4. Ian Hickson. «Server-Sent Events» — первоначальная спецификация (2004).
  5. RFC 7230 — «Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing».
  6. Документация Flask — «Server-Sent Events».
  7. Статья «Server-Sent Events vs WebSocket» — журнал «Хакер» (2022).

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →