Объект WebSocket и его события

Создаём WebSocket из JavaScript и подписываемся на четыре ключевых события.

WebSocket (в браузере) — встроенный объект, который открывает соединение по адресу ws:///wss:// и оповещает код о событиях через колбэки.

Создание соединения

Достаточно одной строки — конструктору передают адрес. Соединение начинает устанавливаться сразу:

// Браузер: открываем канал к серверу
const socket = new WebSocket("wss://example.com/chat");

Объект socket создаётся мгновенно, но канал ещё не готов: рукопожатие идёт асинхронно. Поэтому всю работу строят на событиях.

Четыре события

СобытиеКогда срабатывает
openрукопожатие прошло, канал готов
messageпришли данные от сервера
closeсоединение закрылось
errorпроизошла ошибка
const socket = new WebSocket("wss://example.com/chat");

socket.onopen = () => {
  console.log("Канал открыт");
};

socket.onmessage = (event) => {
  console.log("Пришло:", event.data);
};

socket.onclose = (event) => {
  console.log("Закрыто, код:", event.code);
};

socket.onerror = () => {
  console.log("Ошибка соединения");
};

Жизненный цикл

new WebSocket()
      |
      v
 CONNECTING  (идёт рукопожатие)
      |
   onopen
      |
      v
    OPEN  <----> onmessage / send()  (обмен)
      |
   onclose
      |
      v
   CLOSED

Свойство socket.readyState хранит текущую стадию числом: 0 — CONNECTING, 1 — OPEN, 2 — CLOSING, 3 — CLOSED.

Как работает под капотом

Браузер сам выполняет рукопожатие, держит TCP-соединение, разбирает входящие фреймы и собирает из них сообщения. Когда сообщение собрано целиком — он вызывает ваш onmessage в основном потоке JavaScript. Поэтому колбэки выполняются по очереди, как и остальной ваш код: блокировать их долгими вычислениями нельзя.

Частые ошибки

  • Слать данные до open. Вызов send() в состоянии CONNECTING бросит ошибку — отправляйте внутри onopen или проверяйте readyState === 1.
  • Игнорировать onclose. Без обработки закрытия пользователь не узнает об обрыве и не сработает реконнект.
  • Путать error и close. После error почти всегда идёт close; основную логику переподключения вешают на close.

Итоги

  • WebSocket создаётся одной строкой, но канал готов только после события open.
  • Четыре события: open, message, close, error.
  • readyState показывает стадию (CONNECTING/OPEN/CLOSING/CLOSED).
  • Колбэки выполняются в основном потоке JS — не блокируйте их.
Проверьте себя
1. В какой момент канал готов к отправке данных?
AСразу после new WebSocket()
BПосле события open
CПосле первого message
DПосле close
2. Какое свойство хранит текущую стадию соединения?
Asocket.state
Bsocket.readyState
Csocket.status
Dsocket.phase
3. Что произойдёт при вызове send() в состоянии CONNECTING?
AДанные поставятся в очередь автоматически
BБудет выброшена ошибка
CСоединение закроется
DНичего, сообщение просто проигнорируется без ошибки