FAST Element — это современная библиотека для создания Web Components на JavaScript, предоставляющая удобный синтаксис для декларативного описания компонентов и управления состоянием. Интеграция WebSocket в FAST Element позволяет создавать интерактивные приложения с обновлением данных в реальном времени.
WebSocket — это протокол, обеспечивающий двунаправленное соединение между клиентом и сервером через один TCP-сокет. В отличие от традиционных HTTP-запросов, WebSocket позволяет серверу отправлять данные клиенту без повторных запросов, что критично для чата, мониторинга данных, игровых приложений и других сценариев с высокой частотой обновлений.
Создание соединения на клиенте выглядит следующим образом:
const socket = new WebSocket('ws://localhost:8080');
socket.addEventListener('open', () => {
console.log('Соединение установлено');
});
socket.addEventListener('message', event => {
console.log('Получено сообщение:', event.data);
});
socket.addEventListener('close', () => {
console.log('Соединение закрыто');
});
socket.addEventListener('error', error => {
console.error('Ошибка WebSocket:', error);
});
FAST Element использует классы компонентов, наследуемые от
FASTElement. Для интеграции WebSocket создается свойство,
хранящее объект соединения, и методы для обработки событий.
Пример компонента с подключением к WebSocket:
import { FASTElement, html, css } from '@microsoft/fast-element';
const template = html`
<div>
<h2>Сообщения</h2>
<ul>
${x => x.messages.map(m => html`<li>${m}</li>`)}
</ul>
<input type="text" :value=${x => x.input} @input=${x => x.input = x.event.target.value} />
<button @click=${x => x.sendMessage()}>Отправить</button>
</div>
`;
const styles = css`
div { font-family: Arial, sans-serif; }
ul { list-style: none; padding: 0; }
li { margin: 4px 0; }
`;
export class ChatComponent extends FASTElement {
messages = [];
input = '';
socket;
connectedCallback() {
super.connectedCallback();
this.initWebSocket();
}
disconnectedCallback() {
super.disconnectedCallback();
if (this.socket) {
this.socket.close();
}
}
initWebSocket() {
this.socket = new WebSocket('ws://localhost:8080');
this.socket.addEventListener('open', () => {
console.log('WebSocket соединение открыто');
});
this.socket.addEventListener('message', event => {
this.messages = [...this.messages, event.data];
});
this.socket.addEventListener('close', () => {
console.log('WebSocket соединение закрыто');
});
this.socket.addEventListener('error', error => {
console.error('Ошибка WebSocket:', error);
});
}
sendMessage() {
if (this.input && this.socket.readyState === WebSocket.OPEN) {
this.socket.send(this.input);
this.input = '';
}
}
}
FASTElement.define({
name: 'chat-component',
template,
styles,
elementClass: ChatComponent
});
FAST Element позволяет реактивно обновлять интерфейс при изменении
состояния. Любое присвоение свойства, используемого в шаблоне,
автоматически вызывает ререндеринг. В примере выше массив
messages обновляется при получении нового сообщения, и
<ul> перерисовывается без ручного вмешательства.
Важно использовать новый массив при изменении данных, а не мутировать старый, чтобы FAST Element корректно детектировал изменения:
this.messages = [...this.messages, newMessage];
FAST Element предоставляет методы жизненного цикла:
connectedCallback и disconnectedCallback. Для
корректного управления соединением WebSocket их следует использовать
следующим образом:
connectedCallback гарантирует,
что сокет будет инициализирован после вставки компонента в DOM.disconnectedCallback
предотвращает утечки памяти и попытки отправки сообщений в
несуществующий компонент.В реальных приложениях соединение может разрываться. Рекомендуется реализовать механизм переподключения:
initWebSocket() {
this.socket = new WebSocket('ws://localhost:8080');
this.socket.addEventListener('open', () => {
console.log('Соединение открыто');
});
this.socket.addEventListener('message', event => {
this.messages = [...this.messages, event.data];
});
this.socket.addEventListener('close', () => {
console.log('Соединение закрыто, переподключение через 3 секунды');
setTimeout(() => this.initWebSocket(), 3000);
});
this.socket.addEventListener('error', () => {
console.error('Ошибка WebSocket');
this.socket.close();
});
}
Для более сложных приложений часто требуется слушать несколько типов сообщений. Для этого можно использовать объект-хранилище подписок:
this.channels = {
chat: [],
notifications: []
};
this.socket.addEventListener('message', event => {
const data = JSON.parse(event.data);
if (data.type && this.channels[data.type]) {
this.channels[data.type] = [...this.channels[data.type], data.payload];
}
});
FAST Element позволяет легко привязать динамические данные к DOM. Для каждого канала можно создать отдельный блок в шаблоне:
<ul>
${x => x.channels.chat.map(msg => html`<li>${msg}</li>`)}
</ul>
<ul>
${x => x.channels.notifications.map(note => html`<li>${note}</li>`)}
</ul>
disconnectedCallback.FAST Element совместно с WebSocket позволяет создавать высокореактивные, масштабируемые и интерактивные компоненты с минимальными затратами кода.