Как получать уведомления событий, отправляемых с сервера (Server-Sent Events)?nodejs-194

Server-Sent Events (SSE) предоставляют простой способ получения push-уведомлений от сервера в веб-приложениях. Рассмотрим полный процесс настройки и работы с SSE на клиентской стороне.

Клиентская реализация SSE

1. Создание подключения

Основной объект для работы — EventSource:

const eventSource = new EventSource('/sse-endpoint');

Параметры конструктора:

  • Первый аргумент — URL endpoint сервера
  • Второй необязательный аргумент — объект настроек:
    const eventSource = new EventSource('/sse-endpoint', {
      withCredentials: true // Для отправки кук и аутентификации
    });
    

2. Обработка событий

Стандартные обработчики:

// Для сообщений без указанного типа события
eventSource.onmessage = (event) => {
  console.log('Получены данные:', event.data);
};

// Для обработки ошибок подключения
eventSource.onerror = (error) => {
  console.error('Ошибка SSE:', error);
  // Автоматическое переподключение через 3 секунды (по умолчанию)
};

Именованные события:

eventSource.addEventListener('stockUpdate', (event) => {
  const stockData = JSON.parse(event.data);
  updateStockTicker(stockData);
});

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

3. Управление подключением

// Закрытие соединения
function stopUpdates() {
  eventSource.close();
  console.log('SSE соединение закрыто');
}

// Проверка состояния
console.log('Состояние соединения:', eventSource.readyState);
// 0 - CONNECTING, 1 - OPEN, 2 - CLOSED

Полный пример клиента

<!DOCTYPE html>
<html>
<head>
  <title>SSE Client</title>
</head>
<body>
  <div id="updates"></div>

  <script>
    const updatesDiv = document.getElementById('updates');

    const eventSource = new EventSource('/updates');

    eventSource.onmessage = (e) => {
      updatesDiv.innerHTML += `<p>${e.data}</p>`;
    };

    eventSource.addEventListener('systemAlert', (e) => {
      alert(`СИСТЕМНОЕ УВЕДОМЛЕНИЕ: ${e.data}`);
    });

    eventSource.onerror = () => {
      updatesDiv.innerHTML += '<p>Ожидание переподключения...</p>';
    };
  </script>
</body>
</html>

Особенности работы клиента

  1. Автоматическое переподключение:

    • При разрыве соединения клиент автоматически пытается переподключиться
    • Интервал переподключения можно задать с сервера:
      retry: 5000\n\n
      
  2. Идентификаторы событий:

    • Клиент отправляет последний полученный ID при переподключении
    • Сервер может использовать это для отправки пропущенных событий
  3. Безопасность:

    • Только GET-запросы
    • Тот же origin (можно использовать CORS)
    • Поддержка credentials (withCredentials)

Оптимизация клиентского кода

  1. Обработка JSON-данных:

    eventSource.addEventListener('data', (e) => {
      const parsedData = JSON.parse(e.data);
      // обработка сложных объектов
    });
    
  2. Управление памятью:

    // Важно закрывать соединение при unmount компонента
    useEffect(() => {
      const eventSource = new EventSource('/updates');
      return () => eventSource.close();
    }, []);
    
  3. Кастомные повторные попытки:

    let reconnectAttempts = 0;
    const maxReconnectAttempts = 5;
    
    eventSource.onerror = () => {
      if (reconnectAttempts++ > maxReconnectAttempts) {
        eventSource.close();
        showConnectionError();
      }
    };
    

Отладка SSE

  1. Проверка соединения:

    • В DevTools → Network фильтровать по типам "EventSource"
    • Проверять статус соединения (200) и content-type ("text/event-stream")
  2. Мониторинг событий:

    • В Chrome DevTools можно отслеживать поступающие события
    • Фильтр "EventStream" в вкладке Network

Резюмируем:


Для получения SSE уведомлений клиент создает объект EventSource, подписывается на стандартные (onmessage) и кастомные события через addEventListener. Соединение автоматически поддерживается и восстанавливается при разрывах. Важно правильно обрабатывать ошибки и закрывать соединение, когда оно больше не нужно. SSE идеально подходит для реализации реальных обновлений в дашбордах, уведомлениях и других сценариях, где требуется односторонняя коммуникация сервер→клиент.