WebSocket — протокол связи поверх TCP-соединения, предназначенный для обмена сообщениями между браузером и веб-сервером в режиме реального времени.
В настоящее время в W3C осуществляется стандартизация API Web Sockets. Черновой вариант стандарта этого протокола утверждён IETF.
WebSocket разработан для воплощения в веб-браузерах и веб-серверах, но он может быть использован для любого клиентского или серверного приложения. Протокол WebSocket — это независимый протокол, основанный на протоколе TCP. Он делает возможным более тесное взаимодействие между браузером и веб-сайтом, способствуя распространению интерактивного содержимого и созданию приложений реального времени.
Протокол WebSocket
(стандарт RFC 6455) предназначен для решения любых задач и снятия ограничений обмена данными между браузером и сервером.
Он позволяет пересылать любые данные, на любой домен, безопасно и почти без лишнего сетевого трафика.
Установление WebSocket-соединения
Протокол WebSocket
работает над TCP.
Это означает, что при соединении браузер отправляет по HTTP специальные заголовки, спрашивая: «поддерживает ли сервер WebSocket?».
Если сервер в ответных заголовках отвечает «да, поддерживаю», то дальше HTTP прекращается и общение идёт на специальном протоколе WebSocket, который уже не имеет с HTTP ничего общего.
Установление соединения
Пример запроса от браузера при создании нового объекта new WebSocket("ws://server.example.com/chat")
:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Origin: http://javascript.ru
Sec-WebSocket-Key: Iv8io/9s+lYFgZWcXczP8Q==
Sec-WebSocket-Version: 13
Описания заголовков:
- GET, Host
- Стандартные HTTP-заголовки из URL запроса
- Upgrade, Connection
- Указывают, что браузер хочет перейти на websocket.
- Origin
- Протокол, домен и порт, откуда отправлен запрос.
- Sec-WebSocket-Key
- Случайный ключ, который генерируется браузером: 16 байт в кодировке Base64.
- Sec-WebSocket-Version
- Версия протокола. Текущая версия: 13.
Все заголовки, кроме GET
и Host
, браузер генерирует сам, без возможности вмешательства JavaScript.
Расширения и подпротоколы
Также возможны дополнительные заголовки Sec-WebSocket-Extensions
и Sec-WebSocket-Protocol
, описывающие расширения и подпротоколы (subprotocol), которые поддерживает данный клиент.
Посмотрим разницу между ними на двух примерах:
- Заголовок
Sec-WebSocket-Extensions: deflate-frame
означает, что браузер поддерживает модификацию протокола, обеспечивающую сжатие данных.Это говорит не о самих данных, а об улучшении способа их передачи. Браузер сам формирует этот заголовок.
- Заголовок
Sec-WebSocket-Protocol: soap, wamp
говорит о том, что по WebSocket браузер собирается передавать не просто какие-то данные, а данные в протоколах SOAP или WAMP («The WebSocket Application Messaging Protocol»). Стандартные подпротоколы регистрируются в специальном каталоге IANA.Этот заголовок браузер поставит, если указать второй необязательный параметр
WebSocket
:var
socket=
new
WebSocket
(
"ws://javascript.ru/ws"
,
[
"soap"
,
"wamp"
]
)
;
При наличии таких заголовков сервер может выбрать расширения и подпротоколы, которые он поддерживает, и ответить с ними.
Например, запрос
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Origin: http://javascript.ru
Sec-WebSocket-Key: Iv8io/9s+lYFgZWcXczP8Q==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: deflate-frame
Sec-WebSocket-Protocol: soap, wamp
Ответ:
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: hsBlbuDTkk24srzEOTBUlZAlC2g= Sec-WebSocket-Extensions: deflate-frame Sec-WebSocket-Protocol: soap
В ответе выше сервер указывает, что поддерживает расширение deflate-frame
, а из запрошенных подпротоколов – только SOAP.
WSS
Соединение WebSocket
можно открывать как WS://
или как WSS://
. Протокол WSS
представляет собой WebSocket над HTTPS.
Кроме большей безопасности, у WSS
есть важное преимущество перед обычным WS
– большая вероятность соединения.
Дело в том, что HTTPS шифрует трафик от клиента к серверу, а HTTP – нет.
Если между клиентом и сервером есть прокси, то в случае с HTTP все WebSocket-заголовки и данные передаются через него. Прокси имеет к ним доступ, ведь они никак не шифруются, и может расценить происходящее как нарушение протокола HTTP, обрезать заголовки или оборвать передачу.
А в случае с WSS
весь трафик сразу кодируется и через прокси проходит уже в закодированном виде. Поэтому заголовки гарантированно пройдут, и общая вероятность соединения через WSS
выше, чем через WS
.
Формат данных
Полное описание протокола содержится в RFC 6455.