10-05-2023
WebSocket — протокол полнодуплексной связи поверх TCP-соединения, предназначенный для обмена сообщениями между браузером и веб-сервером в режиме реального времени.
В настоящее время в W3C осуществляется стандартизация API Web Sockets. Черновой вариант стандарта этого протокола утверждён IETF.
Содержание |
Для установления соединения WebSocket клиент и сервер используют протокол, похожий на HTTP. Клиент формирует особый HTTP-запрос, на который сервер отвечает определенным образом.
До редакции черновика протокола номер 75 включительно соединение WebSocket устанавливалось следующим образом. Запрос клиента:
GET /demo HTTP/1.1 Upgrade: WebSocket Connection: Upgrade Host: example.com Origin: http://example.com WebSocket-Protocol: sample
Ответ сервера, подтверждающий переход на WebSocket:
HTTP/1.1 101 Web Socket Protocol Handshake Upgrade: WebSocket Connection: Upgrade WebSocket-Origin: http://example.com WebSocket-Location: ws://example.com/demo WebSocket-Protocol: sample
Сразу после отправки ответа WebSocket соединение считается установленным, клиент и сервер могут начинать двунаправленный обмен сообщениями по этому же TCP-соединению. Для передачи текстового сообщения (в кодировке UTF-8) необходимо перед ним передать нулевой байт, а после — байт со значением 255.
2 июня 2010 года в протокол WebSocket были внесены поправки, изменившие процедуру установления соединения WebSocket без сохранения обратной совместимости. В 76-ой редакции черновика протокола WebSocket добавлена защита от поддельных запросов. Клиент, поддерживающий новую схему, присылает следующий запрос:
GET /demo HTTP/1.1 Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Key2: 4 @1 46546xW%0l 1 5 Host: example.com Sec-WebSocket-Key1: 12998 5 Y3 1 .P00 Origin: http://example.com WebSocket-Protocol: sample ^n:ds[4U
В запрос добавлены новые заголовки "Sec-WebSocket-Key1" и "Sec-WebSocket-Key2" и 8-байтовое тело запроса. Все они генерируются клиентом случайным образом.
Ответ сервера, подтверждающий переход на WebSocket:
HTTP/1.1 101 Web Socket Protocol Handshake Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Origin: http://example.com Sec-WebSocket-Location: ws://example.com/demo Sec-WebSocket-Protocol: sample 8jKS'y:G*Co,Wxa-
Ответ содержит новые названия заголовков ("Sec-WebSocket-Origin","Sec-WebSocket-Location","Sec-WebSocket-Protocol" вместо "WebSocket-Origin", "WebSocket-Location","WebSocket-Protocol") и 16-байтное тело ответа, вычисляемое следующим образом:
Примечания.
Несмотря на "похожесть" новых запросов и ответов на запросы и ответы протокола HTTP, они таковыми не являются. Например, в запросе есть тело, но в заголовках поле "Content-Length" отсутствует (что нарушает соглашения HTTP).
Серверной части следует поддерживать оба вида клиентов и отличать их по наличию или отсутствию в запросе заголовков Sec-WebSocket-Key1 и Sec-WebSocket-Key2.
В 07-ю версию черновика протокола от 22 апреля 2011 были внесены изменения.
В отличие от протокола 76, согласно которому данные передаются без шифрования[1], каждый байт передаваемых от клиента(браузера) серверу данных в этой версии протокола обязательно маскируется 4-байтовой маской[2]. Она создается для каждого сообщения заново.
Передаваемое сообщение теперь имеет заголовок, в котором содержатся такие данные, как:
Взаимодействие между клиентом и сервером начинается с запроса от клиента:
GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Origin: http://example.com Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 7
Ответ сервера имеет следующий вид:
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= Sec-WebSocket-Protocol: chat
Ответ содержит заголовок Sec-WebSocket-Protocol с единственным протоколом, выбраным сервером (chat) из всех поддерживаемых клиентом (chat, superchat). Заголовок Sec-WebSocket-Accept формируется следующим образом:
11 декабря 2011 года протокол приобрел статус RFC.
Вместо заголовка Sec-WebSocket-Origin теперь используется просто Origin.
Протокол Web Socket определяет две URI схемы, ws: (нешифрованное соединение) и wss: (шифрованное соединение).
Для установки соединения клиентский скрипт создает объект WebSocket, в конструктор которого передает параметр WebSocket URI, и определяет функции обратного вызова при соединении, получении сообщения и разрыве соединения.
<html> <head> <script> var webSocket = new WebSocket('ws://localhost/echo'); webSocket.onopen = function(event) { alert('onopen'); webSocket.send("Hello Web Socket!"); }; webSocket.onmessage = function(event) { alert('onmessage, ' + event.data); webSocket.close(); }; webSocket.onclose = function(event) { alert('onclose'); }; </script> </head> <body> </body> </html>
В настоящее время WebSocket поддерживается в следующих браузерах:
Google Chrome (начиная с версии 4.0.249.0); Apple Safari (начиная с версии 5.0.7533.16); Mozilla Firefox (начиная с версии 4); Opera (начиная с версии 10.70 9067);
В конце ноября 2010 Adam Barth опубликовал результаты исследования надежности используемого протокола. По его результатам выяснилось, что в случае использования прозрачных прокси-серверов, возможна подмена кеша передаваемых данных с тем, что пользователи вместо реальных данных будут получать версию данных от злоумышленника. Проблема оказалась достаточно серьёзной для того, чтобы разработчики Firefox и Opera объявили о том, что в будущих версиях их браузеров поддержка веб-сокетов будет по умолчанию отключена вплоть до устранения проблемы небезопасности данного протокола (хотя осталась возможность их включить).
WebSocket.