Как работать с WebSocket в браузере с помощью JavaScript

«Как работать с WebSocket в браузере с помощью JavaScript» — вопрос из категории Сети, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Работа с WebSocket на стороне клиента (frontend) осуществляется через встроенный в браузеры WebSocket API. Он позволяет установить постоянное двунаправленное соединение с сервером.

Жизненный цикл WebSocket-соединения

  1. Создание объекта WebSocket: Указывается URL сервера, начиная с ws:// (незащищенное) или wss:// (защищенное соединение).
  2. Обработка событий: Навешиваются обработчики на ключевые события жизненного цикла сокета.
  3. Отправка и получение данных: Используются методы send() и событие onmessage.
  4. Закрытие соединения: Соединение закрывается методом close().

Практический пример

Ниже приведен полный пример кода для работы с WebSocket на JavaScript.

// 1. Создаем соединение. Для продакшена всегда используйте 'wss://'
const socket = new WebSocket('wss://sockets.example.com/ws');

// 2. Обработчик события: соединение установлено
socket.onopen = function(event) {
  console.log("Соединение установлено.");
  // Отправляем сообщение на сервер после успешного подключения
  socket.send(JSON.stringify({ type: 'greeting', payload: 'Hello Server!' }));
};

// 3. Обработчик события: получено сообщение от сервера
socket.onmessage = function(event) {
  // event.data содержит данные, присланные сервером (обычно в виде строки)
  console.log(`Получены данные: ${event.data}`);

  try {
    const message = JSON.parse(event.data);
    // Обрабатываем полученный объект
    if (message.type === 'notification') {
      alert(`Новое уведомление: ${message.payload}`);
    }
  } catch (error) {
    console.error("Ошибка парсинга JSON:", error);
  }
};

// 4. Обработчик события: соединение закрыто
socket.onclose = function(event) {
  if (event.wasClean) {
    console.log(`Соединение закрыто чисто, код=${event.code}, причина=${event.reason}`);
  } else {
    // Например, сервер оборвал соединение
    console.error('Соединение оборвано');
  }
};

// 5. Обработчик события: произошла ошибка
socket.onerror = function(error) {
  console.error(`Произошла ошибка: ${error.message}`);
};

// Функция для отправки данных по кнопке или другому действию
function sendMessage(text) {
  if (socket.readyState === WebSocket.OPEN) {
    socket.send(JSON.stringify({ type: 'chat', payload: text }));
  } else {
    console.warn('Сокет не открыт. Сообщение не отправлено.');
  }
}

// Закрытие соединения (например, при уходе со страницы)
// window.onbeforeunload = function() {
//   socket.close(1000, "Пользователь покинул страницу");
// };

Ключевые моменты:

  • wss://: В production-среде всегда используйте защищенный протокол wss.
  • Формат данных: Чаще всего для обмена данными используется формат JSON, который перед отправкой сериализуется в строку (JSON.stringify()) и десериализуется при получении (JSON.parse()).
  • readyState: Свойство сокета, которое показывает его текущее состояние: CONNECTING (0), OPEN (1), CLOSING (2), CLOSED (3). Перед отправкой данных полезно проверять, что socket.readyState === WebSocket.OPEN.