SkateJS — это современная библиотека для построения веб-компонентов, ориентированная на реактивность и расширяемость. Одним из важных аспектов динамических веб-приложений является обмен данными в реальном времени, который удобно реализуется через WebSocket. WebSocket позволяет устанавливать двунаправленное соединение между клиентом и сервером, что особенно актуально для компонентов, обновляющихся в режиме реального времени.
В SkateJS соединение с WebSocket обычно инициализируется внутри
жизненного цикла компонента, чаще всего в методе
connectedCallback, чтобы оно активировалось при добавлении
элемента в DOM:
import { define, props, Component } from 'skatejs';
class LiveFeed extends Component {
static props = {
url: props.string
};
connectedCallback() {
super.connectedCallback();
this.socket = new WebSocket(this.url);
this.socket.addEventListener('open', () => {
console.log('Соединение установлено');
});
this.socket.addEventListener('message', (event) => {
this.handleMessage(event.data);
});
this.socket.addEventListener('close', () => {
console.log('Соединение закрыто');
});
this.socket.addEventListener('error', (error) => {
console.error('Ошибка WebSocket:', error);
});
}
disconnectedCallback() {
super.disconnectedCallback();
if (this.socket) {
this.socket.close();
}
}
handleMessage(data) {
// Обновление реактивного свойства компонента
this.data = JSON.parse(data);
}
render() {
return this.data ? `<div>${this.data.message}</div>` : `<div>Загрузка...</div>`;
}
}
define('live-feed', LiveFeed);
В этом примере ключевым моментом является инициализация
сокета в connectedCallback и его закрытие в
disconnectedCallback, что обеспечивает корректное
управление ресурсами и предотвращает утечки памяти при удалении
компонента из DOM.
SkateJS использует реактивные свойства через
props, что позволяет автоматически обновлять DOM при
изменении данных. В сочетании с WebSocket это дает возможность
реализовать динамическое отображение изменений, приходящих с
сервера:
static props = {
data: props.object
};
При поступлении нового сообщения через WebSocket достаточно обновить
this.data, и компонент автоматически перерендерится,
отражая актуальное состояние.
WebSocket позволяет не только получать данные, но и отправлять их. В SkateJS можно создать метод внутри компонента для отправки сообщений:
sendMessage(msg) {
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
this.socket.send(JSON.stringify(msg));
}
}
Важно проверять состояние сокета через readyState, чтобы
избежать ошибок при попытке отправки данных через закрытое
соединение.
Для надежных приложений необходимо учитывать возможность разрыва
соединения. В SkateJS это реализуется через обработку событий
close и error, а также через стратегию
автоматического переподключения:
connect() {
this.socket = new WebSocket(this.url);
this.socket.addEventListener('open', () => {
console.log('Соединение установлено');
});
this.socket.addEventListener('close', () => {
console.log('Соединение закрыто, повторное подключение через 3 секунды');
setTimeout(() => this.connect(), 3000);
});
this.socket.addEventListener('error', (err) => {
console.error('Ошибка WebSocket:', err);
});
}
Такой подход позволяет компоненту сохранять актуальное соединение даже при временных сбоях сети.
SkateJS поддерживает композицию компонентов, поэтому WebSocket можно использовать как источник данных для нескольких компонентов одновременно. Один компонент может получать поток данных, а дочерние компоненты подписываться на его свойства:
class Dashboard extends Component {
static props = {
feedData: props.object
};
connectedCallback() {
super.connectedCallback();
this.liveFeed = this.querySelector('live-feed');
this.liveFeed.addEventListener('data-changed', (e) => {
this.feedData = e.detail;
});
}
render() {
return `<child-component data="${JSON.stringify(this.feedData)}"></child-component>`;
}
}
Использование событий SkateJS (CustomEvent) позволяет
реализовать реактивное распространение данных от одного
компонента к другому без жесткой связи с сервером.
При работе с WebSocket важно учитывать:
requestAnimationFrame или debounce.Объединение всех принципов:
class ChatWidget extends Component {
static props = {
messages: props.array
};
connectedCallback() {
super.connectedCallback();
this.connect();
}
connect() {
this.socket = new WebSocket('wss://chat.example.com');
this.socket.addEventListener('message', (event) => {
const msg = JSON.parse(event.data);
this.messages = [...(this.messages || []), msg];
});
this.socket.addEventListener('close', () => {
setTimeout(() => this.connect(), 2000);
});
}
sendMessage(text) {
if (this.socket.readyState === WebSocket.OPEN) {
this.socket.send(JSON.stringify({ text }));
}
}
render() {
return `
<ul>
${this.messages ? this.messages.map(m => `<li>${m.user}: ${m.text}</li>`).join('') : ''}
</ul>
`;
}
}
define('chat-widget', ChatWidget);
В этом примере реализована полноценная функциональность чата с динамическим обновлением сообщений и автоматическим переподключением. Компонент использует реактивные свойства, безопасную отправку сообщений и аккуратное управление соединением.
SkateJS в сочетании с WebSocket позволяет создавать мощные и реактивные веб-компоненты, полностью ориентированные на динамические данные и интерактивность.