WebSocket соединения

WebSocket — это протокол, обеспечивающий двунаправленное взаимодействие между клиентом и сервером через одно соединение. В контексте Stencil, где создаются веб-компоненты, WebSocket позволяет реализовать динамическое обновление данных, уведомления и интерактивные интерфейсы без постоянного опроса сервера.


Инициализация WebSocket

Для начала работы создается экземпляр объекта WebSocket с указанием URL сервера:

private socket: WebSocket;

componentWillLoad() {
  this.socket = new WebSocket('wss://example.com/socket');
}

Ключевой момент: componentWillLoad используется для инициализации соединения до того, как компонент будет смонтирован в DOM.


Обработка событий WebSocket

WebSocket имеет несколько основных событий:

  • open — соединение установлено;
  • message — получены данные от сервера;
  • error — ошибка соединения;
  • close — соединение закрыто.

Пример обработки событий:

componentWillLoad() {
  this.socket = new WebSocket('wss://example.com/socket');

  this.socket.addEventListener('open', () => {
    console.log('Соединение установлено');
  });

  this.socket.addEventListener('message', (event) => {
    const data = JSON.parse(event.data);
    console.log('Получено сообщение:', data);
  });

  this.socket.addEventListener('error', (error) => {
    console.error('Ошибка WebSocket:', error);
  });

  this.socket.addEventListener('close', () => {
    console.log('Соединение закрыто');
  });
}

Совет: Для сложных приложений стоит вынести обработку событий в отдельные методы компонента для лучшей читаемости и поддержки.


Отправка данных через WebSocket

Данные передаются с помощью метода send. В Stencil часто используется JSON-формат:

sendMessage(data: any) {
  if (this.socket && this.socket.readyState === WebSocket.OPEN) {
    this.socket.send(JSON.stringify(data));
  } else {
    console.warn('Соединение не открыто');
  }
}

Важно: Проверка readyState предотвращает ошибки при попытке отправки сообщений до установления соединения.


Поддержка reconnect

WebSocket может разрываться по различным причинам. Для устойчивости соединения часто реализуют автоматическое переподключение:

private reconnectInterval = 5000;

private connect() {
  this.socket = new WebSocket('wss://example.com/socket');

  this.socket.addEventListener('open', () => {
    console.log('Соединение установлено');
  });

  this.socket.addEventListener('close', () => {
    console.log(`Соединение закрыто, повторная попытка через ${this.reconnectInterval / 1000} секунд`);
    setTimeout(() => this.connect(), this.reconnectInterval);
  });

  this.socket.addEventListener('message', this.handleMessage.bind(this));
}

private handleMessage(event: MessageEvent) {
  const data = JSON.parse(event.data);
  console.log('Получено сообщение:', data);
}

Особенность: Метод bind(this) необходим для сохранения контекста компонента при передаче обработчиков.


Интеграция с состоянием компонента

Stencil использует реактивные свойства (@State) для автоматического обновления DOM при изменении данных. WebSocket-сообщения можно напрямую связывать с состоянием:

@State() messages: string[] = [];

private handleMessage(event: MessageEvent) {
  const data = JSON.parse(event.data);
  this.messages = [...this.messages, data.message];
}

В шаблоне компонента это позволяет динамически отображать список сообщений:

render() {
  return (
    <div>
      {this.messages.map(msg => (
        <p>{msg}</p>
      ))}
    </div>
  );
}

Преимущество: Обновления происходят автоматически без ручного манипулирования DOM.


Безопасность и производительность

  • Использовать wss:// вместо ws:// для защиты данных.
  • Ограничивать количество сообщений, хранящихся в состоянии, чтобы избежать переполнения памяти.
  • Закрывать соединение при размонтировании компонента:
disconnectedCallback() {
  this.socket?.close();
}
  • Обрабатывать ошибки и нестандартные закрытия соединения для обеспечения стабильности приложения.

Примеры практических сценариев

  1. Чат в реальном времени — WebSocket передает новые сообщения и обновляет интерфейс мгновенно.
  2. Мониторинг данных — подключение к серверу для получения телеметрии, графиков или уведомлений.
  3. Игра с многопользовательским режимом — синхронизация действий игроков без задержек.

Использование WebSocket в Stencil позволяет строить реактивные и интерактивные компоненты, полностью реализуя преимущества двунаправленного протокола связи.