Server-Sent Events (SSE) представляют собой механизм однонаправленной связи от сервера к клиенту, позволяющий получать обновления в реальном времени без необходимости постоянного опроса. В контексте FAST Element SSE могут быть интегрированы для динамического обновления интерфейса компонентов без перезагрузки страницы.
Для использования SSE в компонентах FAST Element создается объект
EventSource. Он позволяет подписаться на поток сообщений с
сервера и обрабатывать их через события message,
open и error.
import { FASTElement, html, css } from "@microsoft/fast-element";
const template = html<MySseComponent>`
<div>
<h2>Обновления сервера:</h2>
<ul>
${x => x.messages.map(msg => html`<li>${msg}</li>`)}
</ul>
</div>
`;
const styles = css`
h2 {
color: #333;
font-family: Arial, sans-serif;
}
ul {
padding-left: 20px;
}
`;
export class MySseComponent extends FASTElement {
messages = [];
connectedCallback() {
super.connectedCallback();
this.initSse();
}
initSse() {
const source = new EventSource("/sse-endpoint");
source.ono pen = () => {
console.log("Соединение с сервером установлено");
};
source.onmess age = (event) => {
this.messages = [...this.messages, event.data];
this.$emit("messages-changed");
};
source.oner ror = (error) => {
console.error("Ошибка SSE:", error);
source.close();
};
}
}
FASTElement.define({ name: "my-sse-component", template, styles, elementClass: MySseComponent });
Ключевые моменты:
EventSource автоматически повторно подключается при
разрыве соединения.onmessage используется для обработки каждой новой
порции данных.SSE предоставляет несколько типов событий:
open — срабатывает при успешном
подключении к серверу.message — получает данные от сервера.
Данные могут быть в формате строки, JSON или любом другом, если они
корректно сериализованы.error — срабатывает при проблемах
соединения, например, при недоступности сервера.Можно добавлять кастомные события, используя метод
addEventListener:
source.addEventListener("custom-event", (event) => {
console.log("Кастомное событие:", event.data);
});
Для того чтобы обновления от SSE автоматически отражались в DOM, необходимо использовать реактивные свойства компонентов. FAST Element позволяет легко связывать свойства с шаблоном:
<ul>
${x => x.messages.map(msg => html`<li>${msg}</li>`)}
</ul>
При изменении массива messages можно уведомлять FAST о
необходимости обновления шаблона через $emit с событием
"messages-changed", либо использовать
Observable свойства:
import { observable } from "@microsoft/fast-element";
export class MySseComponent extends FASTElement {
@observable messages = [];
}
На сервере заголовки должны быть следующими:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
Пример простого сервера на Node.js с использованием Express:
const express = require("express");
const app = express();
app.get("/sse-endpoint", (req, res) => {
res.setHeader("Content-Type", "text/event-stream");
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Connection", "keep-alive");
let counter = 0;
const interval = setInterval(() => {
counter++;
res.write(`data: Сообщение ${counter}\n\n`);
}, 2000);
req.on("close", () => {
clearInterval(interval);
});
});
app.listen(3000);
Особенности:
\n\n.SSE передает данные как строки. Для передачи объектов рекомендуется использовать JSON:
res.write(`data: ${JSON.stringify({ text: "Новое событие", timestamp: Date.now() })}\n\n`);
На клиенте данные можно парсить:
source.onmess age = (event) => {
const payload = JSON.parse(event.data);
this.messages = [...this.messages, `${payload.timestamp}: ${payload.text}`];
};
disconnectedCallback), чтобы
избежать утечек памяти:disconnectedCallback() {
if (this.source) {
this.source.close();
}
super.disconnectedCallback();
}
Хотя SSE является простым в реализации и нативно поддерживается браузером, в FAST Element его использование особенно удобно благодаря реактивной системе и декларативному связыванию шаблонов с данными. Это позволяет создавать динамические, интерактивные интерфейсы с минимальной нагрузкой на клиентскую логику.