# WebSocket

> Протокол двустороннего обмена сообщениями между браузером и сервером поверх одного TCP-соединения; начинается как HTTP-запрос и переключается на собственный формат кадров.

Источник: https://llmdocs.ru/wiki/websocket/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Стандарт**: RFC 6455 (декабрь 2011)
- **API браузера**: WHATWG WebSockets Standard
- **Схемы URI**: ws:// (порт 80), wss:// (порт 443, поверх TLS)
- **Работает поверх**: TCP; для HTTP/2 — RFC 8441, для HTTP/3 — RFC 9220
- **Установка**: HTTP Upgrade (код 101)
- **Альтернативы**: Server-Sent Events, long polling, WebTransport
**WebSocket** — сетевой протокол, который открывает между клиентом и сервером постоянный двусторонний канал поверх одного [TCP](https://llmdocs.ru/wiki/tcp.md)-соединения. В отличие от обычного [HTTP](https://llmdocs.ru/wiki/http.md), где клиент спрашивает, а сервер отвечает, по WebSocket любая сторона может отправить сообщение в любой момент. На нём строят чаты, совместное редактирование, биржевые котировки, многопользовательские игры, уведомления и потоковый вывод ответов языковых моделей.

## История

До WebSocket «живые» веб-приложения обходились приёмами вроде частого опроса (polling), долгого опроса (long polling) и Comet — все они расходовали лишние запросы и заголовки. Протокол появился в рамках HTML5 в 2008–2010 годах, после нескольких несовместимых черновиков был стандартизирован IETF как RFC 6455 в 2011 году.[1] Браузерный интерфейс `WebSocket` поддерживает WHATWG.[2] Сегодня его поддерживают все браузеры и серверные платформы.

## Установка соединения

Соединение начинается с обычного HTTP/1.1-запроса с просьбой «сменить протокол»:

```http
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Origin: https://example.com
```

Сервер отвечает кодом `101 Switching Protocols` и заголовком `Sec-WebSocket-Accept` — хешем SHA-1 от присланного ключа с фиксированной строкой. Это не защита, а проверка, что сервер действительно понимает WebSocket. После этого то же TCP-соединение используется для кадров WebSocket. Для [HTTP/2 и HTTP/3](https://llmdocs.ru/wiki/http2-http3.md) определены свои способы открыть WebSocket внутри потока (RFC 8441, RFC 9220).[4]

## Формат кадров

Данные передаются **кадрами** (frames) с компактным заголовком от 2 до 14 байт:

| Поле | Назначение |
|---|---|
| FIN | последний ли это фрагмент сообщения |
| Opcode | тип: текст (UTF-8), двоичные данные, продолжение, close, ping, pong |
| Mask | маскирован ли полезный груз (клиент → сервер — всегда) |
| Payload length | длина: 7 бит, 16 или 64 бита |

Маскирование кадров от клиента случайным ключом защищает промежуточные прокси от атак отравления кэша. Управляющие кадры **ping/pong** проверяют, что соединение живо, а **close** с кодом причины (например, 1000 — нормальное закрытие, 1001 — уход со страницы) завершает его корректно. Расширение `permessage-deflate` сжимает сообщения.[5]

## API в браузере

```javascript
const ws = new WebSocket("wss://example.com/chat");

ws.addEventListener("open", () => ws.send(JSON.stringify({type: "hello"})));
ws.addEventListener("message", (event) => {
  const msg = JSON.parse(event.data);
  console.log("получено:", msg);
});
ws.addEventListener("close", (e) => console.log("закрыто", e.code));
```

Обмен обычно ведут в формате [JSON](https://llmdocs.ru/wiki/json.md). API не умеет само переподключаться — это делает приложение, с экспоненциальной задержкой между попытками.[3]

## Сервер

На сервере WebSocket поддерживают все основные стеки: `ws` и Socket.IO в [Node.js](https://llmdocs.ru/wiki/nodejs.md), `websockets` и Starlette в Python ([FastAPI](https://llmdocs.ru/wiki/fastapi.md)), gorilla/websocket и `nhooyr.io/websocket` в Go, `tokio-tungstenite` в Rust. Socket.IO — не сам WebSocket, а надстройка со своим протоколом: комнаты, подтверждения, автоматическое переподключение и откат на long polling.

Каждое соединение долгоживущее, поэтому серверу нужна асинхронная модель ввода-вывода, а при нескольких экземплярах — общая шина сообщений (Redis Pub/Sub, NATS), чтобы событие с одного сервера дошло до клиентов, подключённых к другому.

## За прокси и балансировщиком

[Обратный прокси](https://llmdocs.ru/wiki/reverse-proxy.md) должен пробрасывать заголовки `Upgrade` и `Connection` и не закрывать неактивные соединения слишком рано. Для [nginx](https://llmdocs.ru/wiki/nginx.md):[6]

```nginx
location /ws/ {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 1h;
}
```

При [балансировке](https://llmdocs.ru/wiki/load-balancing.md) важно, что соединение закреплено за одним сервером на всё время жизни; алгоритм least connections распределяет такие соединения лучше, чем round robin.

## Безопасность

- Используйте `wss://` — WebSocket поверх TLS; незашифрованный `ws://` легко перехватить и блокируется многими сетями.
- Политика same-origin на WebSocket не распространяется: сервер обязан проверять заголовок `Origin`, иначе возможна атака Cross-Site WebSocket Hijacking.
- Аутентификацию выполняют при установке (cookie, токен в первом сообщении); токен в URL попадает в логи.
- Ограничивайте размер сообщений и частоту — открытое соединение легко превратить в канал перегрузки.

## Альтернативы

- **Server-Sent Events (SSE)** — односторонний поток событий от сервера по обычному HTTP; проще, работает через любые прокси, переподключается сам. Именно SSE используют многие API языковых моделей для потокового вывода.
- **Long polling** — запасной вариант для очень старых сред.
- **WebTransport** — новый API поверх HTTP/3 и [QUIC](https://llmdocs.ru/wiki/quic.md) с несколькими потоками и ненадёжными датаграммами.

## См. также

- [HTTP](https://llmdocs.ru/wiki/http.md)
- [TCP](https://llmdocs.ru/wiki/tcp.md)
- [Node.js](https://llmdocs.ru/wiki/nodejs.md)
- [HTTP/2 и HTTP/3](https://llmdocs.ru/wiki/http2-http3.md)

## Источники

1. [RFC 6455 — The WebSocket Protocol](https://www.rfc-editor.org/rfc/rfc6455)
2. [WHATWG — WebSockets Standard](https://websockets.spec.whatwg.org/)
3. [MDN — The WebSocket API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)
4. [RFC 8441 — Bootstrapping WebSockets with HTTP/2](https://www.rfc-editor.org/rfc/rfc8441)
5. [RFC 7692 — Compression Extensions for WebSocket](https://www.rfc-editor.org/rfc/rfc7692)
6. [nginx — WebSocket proxying](https://nginx.org/en/docs/http/websocket.html)
