Logo Craft Homelab Docs Контакты Telegram
Server-Sent Events — Альтернатива WebSocket Трендовые github проекты в нашем телеграм канале. Подпишись 👉
Fri Feb 13 2026

Server-Sent Events: альтернатива WebSocket

Server-Sent Events (SSE) — это часто упускаемая из виду технология для реализации real-time обновлений в веб-приложениях. Когда речь заходит о двусторонней связи, все спешат выбирать между WebSocket и Long Polling, забывая о простом и эффективном решении для односторонних данных. SSE — это не просто “ещё один способ отправлять данные”, а специализированный протокол с рядом архитектурных преимуществ, которые делают его идеальным для сценариев типа логирования, уведомлений или обновлений статуса.

Технический вызов: односторонний push без перегрузки

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

Механика работы SSE

SSE построен на двух ключевых компонентах: специальном MIME-типе text/event-stream и формате сообщений. Сервер открывает HTTP-соединение и отправляет данные в формате, где каждое сообщение начинается с префикса data:, а заканчивается двойным переносом строки \n\n.

HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

data: Это первое сообщение\n\n
data: Второе сообщение\n\n

Формат поддерживает несколько специальных полей:

  • event - тип события (по умолчанию message)
  • id - идентификатор сообщения для отслеживания
  • retry - интер переподключения в миллисекундах

Браузер автоматически обрабатывает эти поля и предоставляет API через EventSource, который поддерживает:

  • Автоматическое переподключение при обрыве связи
  • Распознавание разных типов событий
  • Обработку сообщений с идентификаторами

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

Клиентская часть (JavaScript)

// Создание EventSource с указанием endpoint
const eventSource = new EventSource('/updates');

// Обработка события по умолчанию (тип 'message')
eventSource.onmessage = function(event) {
  console.log('Получены данные:', event.data);
  // Доступны также event.lastEventId
};

// Обработка определенного типа события
eventSource.addEventListener('notification', function(event) {
  const data = JSON.parse(event.data);
  showNotification(data.title, data.body);
});

// Обработка ошибок
eventSource.onerror = function(err) {
  console.error('EventSource failed:', err);
  // Автоматическое переподключение произойдет через экспоненциальный отрезок времени
};

Сервер должен поддерживать CORS, если запрос идет с другого домена, с заголовками:

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

Серверная часть (Node.js)

const http = require('http');

const server = http.createServer((req, res) => {
  // Проверяем, что запрос для SSE
  if (req.headers.accept === 'text/event-stream') {
    
    // Устанавливаем необходимые заголовки
    res.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
      'Access-Control-Allow-Origin': '*'
    });
    
    // Отправляем начальное сообщение
    res.write('data: Соединение установлено\n\n');
    
    // Симуляция отправки данных каждые 5 секунд
    const interval = setInterval(() => {
      const message = {
        timestamp: new Date().toISOString(),
        value: Math.random() * 100
      };
      
      // Форматируем сообщение в SSE формат
      res.write(`data: ${JSON.stringify(message)}\n\n`);
    }, 5000);
    
    // Очистка при закрытии соединения
    req.on('close', () => {
      clearInterval(interval);
      res.end();
    });
  }
});

server.listen(3000, () => console.log('SSE сервер запущен на порту 3000'));

Серверная часть (Python с Flask)

from flask import Flask, Response
import json
import time
import threading

app = Flask(__name__)

def event_stream():
    while True:
        # Генерируем данные
        data = {
            'timestamp': time.time(),
            'value': int(time.time() * 1000) % 100
        }
        
        # Форматируем как SSE сообщение
        yield f"data: {json.dumps(data)}\n\n"
        time.sleep(1)

@app.route('/updates')
def updates():
    # Используем Streaming Response для SSE
    return Response(
        event_stream(),
        mimetype='text/event-stream',
        headers={
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'Access-Control-Allow-Origin': '*'
        }
    )

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

Узкие места и компромиссы

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

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

  2. Ограниченная поддержка кросс-доменных запросов - По умолчанию SSE работает только с тем же источником (same-origin). Для кросс-доменных запросов требуется серверная поддержка CORS, что может быть проблемой в некоторых корпоративных сетях.

  3. Нет встроенного шифрования - SSE полагается на HTTPS для шифрования данных, но в отличие от WebSocket, не имеет встроенного механизма шифрования на уровне протокола.

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

  5. Проблемы с балансировщиками - SSE использует долгоживущие HTTP-соединения, что может вызывать проблемы с балансировщиками нагрузки, которые ожидают завершения HTTP-запроса. Требуется специальная настройка балансировщиков.

  6. Ограниченная поддержка браузеров - Хотя все современные браузеры поддерживают SSE, мобильные браузеры (особенно iOS Safari) могут ограничивать время жизни соединений в фоновом режиме.

Когда использовать SSE, а когда искать альтернативы

SSE идеален для:

  • Систем мониторинга и дашбордов
  • Логирования в реальном времени
  • Уведомлений о событиях
  • Обновлений статуса
  • Аукционов в реальном времени
  • Прогресс-баров для долгих операций

SSE не подходит для:

  • Чатов и мессенджеров
  • Интерактивных игр
  • Онлайн-редакторов с совместной работой
  • Систем, где клиент должен активно отправлять данные

Если ваша задача требует двунаправленной связи, но не требует низкой задержки, рассмотрите REST API с короткими опросами. Для сценариев с высокой частотой обновлений и двунаправленной связью без компромиссов остается только WebSocket. Но для множества задач SSE предлагает идеальный баланс сложности и функциональности — простая, надежная и эффективная технология, которая не усложняет архитектуру без необходимости.