Короткий ответ: WebSocket protocol — это стандарт постоянного двустороннего соединения между клиентом и сервером. Он начинается как HTTP-запрос с Upgrade, затем соединение переходит в WebSocket-режим, и стороны обмениваются фреймами
Простая схема:
HTTP request -> Upgrade -> WebSocket connection -> frames/messages
HTTP Upgrade
Клиент сначала отправляет HTTP-запрос на WebSocket endpoint. Если сервер поддерживает протокол, он отвечает переключением протокола. После этого канал остается открытым
В прикладном JavaScript это скрыто за строкой:
const socket = new WebSocket("wss://example.com/ws");
Но под капотом браузер делает handshake и проверяет ответ сервера
ws и wss
ws:// — обычное WebSocket-соединение. Его удобно использовать локально:
ws://localhost:8080
wss:// — защищенное WebSocket-соединение через TLS:
wss://example.com/ws
На HTTPS-сайте используйте wss://, иначе браузер может заблокировать соединение
Фреймы и сообщения
Приложение обычно думает сообщениями: строка, JSON, бинарный блок. Протокол передает эти данные фреймами. Большое сообщение может быть разделено на несколько фреймов
В браузере вы чаще видите только событие:
socket.addEventListener("message", (event) => {
console.log(event.data);
});
Фрейминг, маскировка, длина payload и opcode скрыты от прикладного кода
Ping, pong и close
В протоколе есть управляющие фреймы:
- ping;
- pong;
- close.
Они помогают проверять живость соединения и корректно закрывать канал. В браузерном API вы не отправляете ping-фрейм вручную: этим занимается реализация. На сервере библиотеки часто дают свои методы для heartbeat
Закрытие в JS:
socket.close(1000, "Normal close");
Код 1000 означает нормальное закрытие
Маскировка
Клиентские фреймы к серверу маскируются. Это не шифрование, а правило протокола. Если вы используете браузер или библиотеку, маскировку делать вручную не нужно
Шифрование обеспечивает TLS, то есть wss://, а не сама маскировка
Чем протокол отличается от API
WebSocket API — это то, чем вы пользуетесь в браузере:
new WebSocket(url)
WebSocket protocol — это правила обмена на сетевом уровне: handshake, фреймы, opcode, close codes, masking
Новичку для приложения обычно достаточно API. Протокол нужен, если вы пишете сервер, прокси, отладчик или низкоуровневую реализацию
Что важно знать прикладному разработчику
Даже если вы не реализуете протокол вручную, полезно помнить три вещи
Первое: WebSocket-соединение долго живет, поэтому сервер должен учитывать память, лимиты клиентов и отключения
Второе: сообщения могут быть текстовыми и бинарными. Договоритесь о формате: например, JSON с полем type
Третье: протокол не дает бизнес-очередь сам по себе. Если вам нужны request-response, подтверждения доставки или повторная отправка, это нужно строить поверх WebSocket
Пример прикладного сообщения:
{
"type": "order_updated",
"requestId": "abc-123",
"payload": {
"orderId": 42,
"status": "paid"
}
}
Такой слой уже относится к вашему приложению, а не к RFC
Частые ошибки
Первая ошибка — думать, что WebSocket начинается без HTTP. На старте используется HTTP Upgrade
Вторая ошибка — путать wss и маскировку. wss шифрует канал, маскировка — протокольная операция для клиентских фреймов
Третья ошибка — вручную собирать фреймы в обычном веб-приложении. Для этого есть браузер и библиотеки
Четвертая ошибка — не понимать, что WebSocket соединение постоянное. Его нужно закрывать и мониторить
Пятая ошибка — ждать гарантий доставки как у очереди сообщений. WebSocket доставляет данные по соединению, но не хранит их после обрыва. Если событие критичное, проектируйте повторную синхронизацию
Самопроверка
Откройте DevTools, вкладку Network, фильтр WS. Подключитесь к WebSocket и посмотрите, как в браузере отображаются отправленные и полученные сообщения. Это не весь протокол, но хороший практический старт
Что почитать дальше по WebSocket
Если нужен общий маршрут по теме, откройте рубрику WebSocket. Для соседних задач пригодятся эти разборы:
- Nginx и WebSocket proxy: почему локально работает, а на сервере нет
- WebSocket: что это, как работает и как запустить первый пример
- Как работает WebSocket: соединение, сообщения и закрытие
- Django: как подружить Celery с WebSocket



