SSE — що це, Server-Sent Events та односторонній стримінг

Автор: IT Sectr Опубліковано: 2026-06-02 Час читання: 8 хв

SSE (Server-Sent Events) — це стандарт W3C, що дозволяє серверу надсилати потокові дані клієнту через одне HTTP-з’єднання в односторонньому режимі. На відміну від WebSocket, SSE працює поверх звичайного HTTP і не потребує спеціального протоколу чи бібліотеки на стороні клієнта. Згідно з специфікацією W3C HTML Living Standard (2025), EventSource API підтримується в усіх сучасних браузерах, включаючи Chrome, Firefox, Safari та Edge.

Головне

  • SSE — це стандарт односторонньої передачі даних від сервера до клієнта через HTTP-з’єднання.
  • EventSource API — це вбудований браузерний інтерфейс для прийому SSE без зовнішніх бібліотек.
  • Автоматичне перепід’єднання — браузер автоматично відновлює з’єднання при обриві.
  • Текстовий протокол — дані передаються у форматі text/event-stream з простим текстовим форматом.
  • Односторонній зв’язок — SSE підходить для сповіщень, стрічок новин, тікерів та моніторингу, але не для чатів.

Що таке SSE?

SSE (Server-Sent Events) — це технологія, яка дозволяє веб-серверу надсилати дані клієнту в будь-який момент після встановлення з’єднання. Вона стандартизована WHATWG як частина HTML Living Standard і використовує тип MIME text/event-stream. SSE підтримує передачу текстових даних з можливістю зазначення ідентифікатора повідомлення, типу події та затримки перепід’єднання.

На відміну від WebSocket, який потребує двостороннього протоколу та запиту на оновлення, SSE працює поверх звичайного HTTP. Сервер встановлює заголовок Content-Type: text/event-stream, надсилає дані частинами та тримає з’єднання відкритим. Клієнт отримує дані через браузерний EventSource API, який автоматично аналізує потік та генерує події.

Згідно з CanIUse (2025), EventSource API підтримується в 97,5% браузерів глобально. Він не підтримується в Internet Explorer та деяких мобільних браузерах (Samsung Internet до версії 7.0). Для цих випадків існують поліфіли, які емулюють EventSource через XHR стрімінг. SSE не працює з HTTP/1.1 pipelining, але повністю сумісний з HTTP/2 server push.

Історія та стандартизація

SSE був запропонований як частина специфікації HTML5 у 2009 році під назвою Server-Sent DOM Events. Перша реалізація з’явилася в Opera 9.0, потім у Firefox 6.0 (2011), Chrome 9.0 (2011) та Safari 5.0 (2010). У 2015 році специфікацію було перенесено до окремого розділу HTML Living Standard. Незважаючи на десятилітню історію, SSE залишається менш популярним, ніж WebSocket, через свою односторонню природу.

Як працює SSE

Механізм роботи SSE наступний: клієнт створює екземпляр EventSource з URL серверної точки закінчення. Браузер надсилає GET-запит із заголовком Accept: text/event-stream. Сервер відповідає статусом 200 OK та заголовком Content-Type: text/event-stream, після чого починає надсилати дані у форматі event-stream. З’єднання залишається відкритим, поки сервер не надішле сигнал завершення або клієнт не викличе close().

На стороні сервера дані надсилаються частинами (chunked transfer encoding). Кожен блок даних — це текстове повідомлення, що складається з рядків полів (event, data, id, retry). Сервер може надсилати повідомлення в будь-який момент, що робить SSE ідеальним для сповіщень та оновлень статусу. З’єднання не потребує постійного обміну пакетами heartbeat (як WebSocket), хоча поле retry керує частотою перепід’єднання.

Згідно з тестами продуктивності (2024), SSE забезпечує пропускну здатність до 10 000 повідомлень на секунду на одне з’єднання при розмірі повідомлення 256 байтів. На стороні сервера кожне SSE-з’єднання споживає приблизно 5–10 КБ пам’яті, що дозволяє одному серверу підтримувати 50 000+ одночасних з’єднань з 1 ГБ RAM. Це значно менше, ніж у WebSocket, через відсутність бінарного протоколу.

Формат event-stream

Формат text/event-stream — це простий текстовий протокол, де кожне повідомлення складається з іменованих полів, розділених символами нового рядка. Кожне поле має формат «Ім’я поля: значення». Повідомлення розділяються двома символами нового рядка (\n\n).

Підтримувані поля: event (тип події, типово message), data (рядок даних, може бути багаторядковим), id (останній ідентифікатор події, зберігається в Last-Event-ID), retry (час перепід’єднання в мілісекундах). Коментарі починаються з двокрапки (:) та ігноруються парсером, але можуть використовуватися для heartbeat.

ПолеОбов’язковеПризначення
eventНіТип події (типово message)
dataТакРядок даних повідомлення
idНіІдентифікатор події для Last-Event-ID
retryНіЗатримка перепід’єднання в мс

Приклад потоку event-stream

text
: heartbeat comment
event: update
data: {"user": "Alice", "action": "typing"}
id: 1001

event: notification
data: {"type": "info", "text": "New version available"}
data: {"type": "action", "url": "/upgrade"}
retry: 3000

event: close
data: Session ended

EventSource API на клієнті

EventSource API — це вбудований браузерний інтерфейс для прийому SSE. Для створення з’єднання достатньо викликати конструктор з URL точки закінчення. EventSource автоматично встановлює з’єднання, обробляє перепід’єднання та аналізує вхідні повідомлення в JavaScript-події.

Події EventSource: open (з’єднання встановлено), message (отримано повідомлення без зазначення події), error (помилка з’єднання). Для користувацьких подій (event: custom) можна використовувати addEventListener з іменем події. EventSource автоматично надсилає заголовок Last-Event-ID при перепід’єднанні, що дозволяє серверу відновити потік з перерваного місця.

Згідно з документацією MDN (2025), EventSource підтримує CORS та передачу облікових даних (withCredentials). EventSource не підходить для надсилання користувацьких заголовків або тіла запиту — потрібна ручна реалізація через fetch + ReadableStream. EventSource не підтримує бінарні дані — тільки текст та JSON.

Клієнтський код JavaScript

js
const eventSource = new EventSource('/api/events/stream');

eventSource.addEventListener('open', () => {
    console.log('З’єднання SSE відкрито');
});

eventSource.addEventListener('message', (event) => {
    const data = JSON.parse(event.data);
    console.log('Отримано:', data);
    renderUpdate(data);
});

eventSource.addEventListener('notification', (event) => {
    const notification = JSON.parse(event.data);
    showNotification(notification.text);
});

eventSource.addEventListener('error', (error) => {
    console.error('Помилка SSE:', error);
    // Браузер автоматично перепід’єднується
});

// Закрити з’єднання
eventSource.close();

SSE vs WebSocket: порівняння

SSE та WebSocket — різні технології для real-time комунікації, кожна зі своїми сильними сторонами. WebSocket підходить для двостороннього обміну даними (чати, ігри, спільне редагування), SSE — для односторонніх потоків від сервера до клієнта (сповіщення, стрічки новин, тікери).

Ключова відмінність — WebSocket потребує запиту на оновлення з HTTP/1.1 до протоколу WebSocket (ws://), що може блокуватися корпоративними проксі. SSE працює поверх звичайного HTTP, проходить через будь-які проксі та не потребує спеціальної конфігурації сервера. SSE також простіший у реалізації — серверу не потрібна додаткова бібліотека, достатньо правильно сформувати HTTP-відповідь.

Згідно з порівняльним тестуванням (2024), на одному серверному процесі SSE підтримує на 30–50% більше з’єднань, ніж WebSocket, через простіший протокол. Однак latency у SSE вища (50–200 мс проти 10–50 мс у WebSocket) через те, що SSE використовує chunked HTTP, а не повноцінний двонаправлений потік з бінарними фреймами.

ХарактеристикаSSEWebSocket
НапрямСервер → клієнтДвосторонній
ПротоколHTTP (text/event-stream)ws:// / wss:// (RFC 6455)
Браузери97,5% (вбудований EventSource)97% (вбудований WebSocket)
ДаніТільки текст / JSONТекст + бінарні (Blob, ArrayBuffer)
Обробка проксіПроходить будь-які проксіПотребує налаштування проксі
Перепід’єднанняАвтоматичне (браузер)Ручна реалізація
ІсторіяLast-Event-IDНемає вбудованої історії

Як реалізувати SSE на сервері

Реалізація SSE на сервері не потребує бібліотек — достатньо встановити правильні HTTP-заголовки та надсилати дані у форматі text/event-stream. Розглянемо приклад на Node.js з використанням вбудованого модуля http. Сервер встановлює заголовки Content-Type та Cache-Control, після чого надсилає повідомлення кожні N секунд.

Згідно з MDN Web Docs (2025), обов’язкові заголовки для SSE: Content-Type: text/event-stream, Cache-Control: no-cache та Connection: keep-alive. Без Cache-Control браузер може закешувати SSE-потік, що призведе до зупинки доставки. Connection: keep-alive явно вказує браузеру тримати з’єднання відкритим.

Серверний код на Node.js

js
const http = require('http');

http.createServer((req, res) => {
    res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive'
    });

    let eventId = 0;
    const interval = setInterval(() => {
        eventId++;
        res.write(`id: ${eventId}\n`);
        res.write(`event: update\n`);
        res.write(`data: {"time": "${new Date().toISOString()}", "id":${eventId}}\n\n`);
    }, 2000);

    req.on('close', () => {
        clearInterval(interval);
    });
}).listen(3000);

SSE на Python (Flask)

python
from flask import Response, Flask
import time
import json

app = Flask(__name__)

@app.route('/stream')
def stream():
    def generate():
        event_id = 0
        while True:
            event_id += 1
            data = json.dumps(
                {'ticker': 'AAPL', 'price': 150.25})
            yield f'id: {event_id}\nevent: price\ndata: {data}\n\n'
            time.sleep(1)
    return Response(generate(),
        mimetype='text/event-stream')

SSE в мобільних додатках

Використання SSE в мобільних додатках обмежено відсутністю нативної реалізації EventSource для iOS та Android. На мобільних платформах SSE реалізується через сторонні бібліотеки: на iOS — через URLSession з NSURLProtocol, на Android — через OkHttp з SSE-підтримкою (okhttp-sse). Для React Native та Flutter доступні пакети, які емулюють EventSource.

На iOS нативна реалізація SSE можлива через URLSessionDataDelegate. При отриманні даних у методі urlSession(_:dataTask:didReceive:) додаток накопичує буфер і аналізує event-stream формат вручну. Згідно з блогом iOS-розробки (2024), споживання батареї при SSE на iOS на 40% нижче, ніж при постійному WebSocket-з’єднанні, через відсутність heartbeat-пакетів.

На Android OkHttp надає клас EventSource.Factory для підписки на SSE-потоки. Android-додатки можуть використовувати SSE для сповіщень, коли FCM недоступний, або для синхронізації даних у фоновому режимі. SSE на Android добре працює з WorkManager для довгоживучих фонових завдань. Згідно з документацією OkHttp (2025), okhttp-sse підтримує автоматичне перепід’єднання з кастомним listener.

Часто задавані питання

Чим SSE відрізняється від WebSocket?

SSE — одностороння передача (сервер → клієнт) поверх HTTP, не потребує бібліотек на клієнті. WebSocket — двостороння передача з бінарним протоколом. SSE простіший у реалізації, WebSocket підходить для завдань, де клієнт теж надсилає дані.

Чи підтримує SSE бінарні дані?

Ні, SSE передає тільки текстові дані. Для бінарних даних (зображення, аудіо) потрібне кодування Base64, яке збільшує розмір на 33%. Для бінарних потоків краще використовувати WebSocket.

Як SSE обробляє обриви з’єднання?

EventSource автоматично перепід’єднується при обриві. Час затримки задається полем retry в потоці (типово 1000 мс). При перепід’єднанні браузер надсилає заголовок Last-Event-ID, що дозволяє серверу відновити потік з перерваного місця.

Скільки з’єднань SSE може тримати браузер?

Кожен браузер має обмеження на кількість одночасних HTTP-з’єднань з одним доменом. Для HTTP/1.1 — 6–8 з’єднань на домен, для HTTP/2 — до 100. SSE використовує одне з’єднання, тому конкуренції з іншими запитами не виникає.

Чи можна використовувати SSE для чату?

SSE підходить тільки для отримання повідомлень (вхідні). Для надсилання повідомлень (вихідні) потрібен окремий HTTP-запит (POST). Для повноцінного чату зручніше використовувати WebSocket або Socket.IO з двостороннім зв’язком в одному з’єднанні.

Підсумки

  • SSE — стандарт односторонньої передачі даних від сервера до клієнта через звичайне HTTP-з’єднання без додаткових бібліотек.
  • EventSource API — вбудований браузерний інтерфейс, підтримуваний 97,5% сучасних браузерів.
  • Простий текстовий протокол text/event-stream з полями event, data, id та retry.
  • Автоматичне перепід’єднання з підтримкою Last-Event-ID для відновлення потоку з перерваного місця.
  • Ефективність — SSE підтримує більше з’єднань на сервері (50 000+) порівняно з WebSocket за рахунок простішого протоколу.
  • На мобільних платформах SSE реалізується через OkHttp (Android) або URLSession (iOS) з ручним аналізом потоку.
  • Для односторонніх потоків (сповіщення, стрічки, тікери) вибирайте SSE, для двостороннього зв’язку — WebSocket або Socket.IO.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також