Server-Sent Events (SSE) представляют собой технологию, которая позволяет серверу отправлять обновления в реальном времени на веб-страницу через однонаправленное соединение HTTP. Это полезно для приложений, которым необходимо получать данные от сервера без постоянного опроса (polling) или использования более сложных механизмов, таких как WebSockets.
SSE идеально подходит для ситуаций, когда нужно передавать поток данных от сервера клиенту, например, для отображения новостей, обновлений о статусах, чатов или систем мониторинга.
Для работы с SSE достаточно использовать стандартный HTTP-протокол и соответствующий API в JavaScript. В отличие от WebSockets, который представляет собой двустороннее соединение, SSE предполагает, что сервер инициирует обновления, а клиент только получает их.
Процесс взаимодействия включает несколько ключевых этапов:
text/event-stream.Для реализации SSE на сервере можно использовать любой серверный фреймворк, который поддерживает отправку данных по протоколу HTTP. Пример на Node.js с использованием Express:
const express = require('express');
const app = express();
const port = 3000;
app.get('/events', (req, res) => {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.flushHeaders(); // Начинаем отправку данных
const intervalId = setInterval(() => {
res.write(`data: ${JSON.stringify({ message: 'Обновление данных!' })}\n\n`);
}, 1000); // отправка данных каждую секунду
req.on('close', () => {
clearInterval(intervalId); // Закрытие соединения по окончании работы клиента
});
});
app.listen(port, () => {
console.log(`Сервер запущен на http://localhost:${port}`);
});
Здесь сервер на Express слушает запросы по маршруту
/events и отправляет данные с интервалом в одну секунду.
Ключевые заголовки для SSE включают
Content-Type: text/event-stream,
Cache-Control: no-cache и
Connection: keep-alive, чтобы установить и поддерживать
открытое соединение.
На клиентской стороне взаимодействие с сервером реализуется с
использованием объекта EventSource. Этот объект позволяет
подписаться на события, которые сервер отправляет в реальном
времени.
Пример клиента, который подключается к серверу SSE:
const eventSource = new EventSource('/events');
eventSource.onmess age = function(event) {
const data = JSON.parse(event.data);
console.log(data.message); // Обработка поступившего сообщения
};
eventSource.oner ror = function(error) {
console.error("Ошибка SSE:", error);
};
Объект EventSource автоматически устанавливает
соединение с сервером и прослушивает поступающие сообщения. Каждое
событие, отправленное сервером, будет вызывать обработчик
onmessage. В случае ошибок (например, если соединение
разорвано), будет вызван обработчик onerror.
Сообщения, отправляемые через SSE, следуют строгому формату. Каждый кусок данных должен начинаться с ключевого слова, за которым следует двоеточие и данные. Возможные поля:
data: основное содержимое сообщения.id: уникальный идентификатор события, используемый для
отслеживания последнего события.event: название события.retry: указание на время (в миллисекундах), через
которое клиент должен повторить попытку подключения, если соединение
было закрыто.Пример сообщения:
id: 123
event: update
data: {"message": "Новое сообщение на сервере!"}
В данном примере передается сообщение с ID, типом события и самими
данными. Поле retry используется сервером для указания, как
часто клиент должен пытаться переподключиться в случае потери
соединения.
Одной из особенностей SSE является поддержание соединения в открытом
состоянии, что позволяет серверу отправлять данные в любой момент
времени. Когда клиент больше не заинтересован в получении обновлений, он
может закрыть соединение с сервером с помощью метода
close() объекта EventSource:
eventSource.close(); // Закрытие соединения
Сервер, в свою очередь, может управлять временем жизни соединения.
Например, если сервер решит, что необходимо закрыть соединение, он может
завершить его вручную или по таймеру. Когда соединение закрыто, клиент
автоматически получит событие error.
Solid.js — это современный реактивный фреймворк, который обеспечивает эффективное обновление UI с минимальными затратами. SSE может быть легко интегрирован в приложение на Solid.js с использованием реактивных состояний и подписок.
Пример использования SSE с Solid.js:
import { createSignal, onCleanup } from 'solid-js';
function App() {
const [message, setMessage] = createSignal('');
const eventSource = new EventSource('/events');
eventSource.onmess age = (event) => {
const data = JSON.parse(event.data);
setMessage(data.message); // Обновление состояния при получении данных
};
onCleanup(() => {
eventSource.close(); // Закрытие соединения при удалении компонента
});
return (
<div>
<h1>Полученное сообщение:</h1>
<p>{message()}</p>
</div>
);
}
export default App;
В этом примере создается сигнал message, который
обновляется при получении новых данных от сервера. Использование функции
onCleanup позволяет закрыть соединение SSE, когда компонент
больше не нужен.
Server-Sent Events — это эффективный способ передачи данных от сервера к клиенту в реальном времени, с минимальными затратами на ресурсы и с гарантией надежности благодаря встроенному механизму автоматического восстановления соединения. В связке с такими фреймворками, как Solid.js, SSE позволяет строить производительные и реактивные веб-приложения, эффективно обновляющие данные без лишней нагрузки на сервер и клиента.