Сетевой протокол: формат сообщения WebSocket

задняя часть WebSocket Сетевой протокол

Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность

Введение

Мы знаем, что WebSocket — это сетевой протокол, основанный на протоколе TCP, который используется для связи в реальном времени между клиентом и сервером. Очень полезно. Самый простой способ использовать WebSocket — использовать API браузера для прямой связи с сервером.

В этой статье будет глубоко проанализирован формат взаимодействия сообщений WebSocket, чтобы каждый мог понять, как работает websocket.

Процесс рукопожатия WebSocket

Мы знаем, что WebSocket обновляется на основе протокола HTTP, чтобы быть совместимым с протоколом HTTP. После того, как клиент и сервер установили HTTP-соединение, клиент отправляет на сервер обновление протокола до webSocket, как показано ниже:

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

Обратите внимание, что версия HTTP здесь должна быть выше 1.1. Метод HTTP-запроса должен быть GET

Установив два заголовка Upgrade и Connection, мы готовы перейти на webSocket.

В дополнение к перечисленным здесь свойствам допустимы и другие свойства заголовка HTTP.

Здесь есть еще два специальных заголовка, это Sec-WebSocket-Version и Sec-WebSocket-Key.

Давайте сначала посмотрим на Sec-WebSocket-Version, который указывает номер версии WebSocket, запрошенный клиентом. Если сервер не понимает запрос, отправленный клиентом, он вернет 400 («Неверный запрос»), в котором сервер вернет сообщение об ошибке.

Если он не понимает Sec-WebSocket-Version, отправленную клиентом, сервер также вернет Sec-WebSocket-Version, чтобы проинформировать клиента.

Одно поле заголовка, на которое следует обратить особое внимание, — это Sec-WebSocket-Key. Давайте посмотрим, для чего используется это поле.

Когда сервер получает запрос клиента, он возвращает ответ клиенту, сообщая клиенту, что протокол был обновлен с HTTP до WebSocket.

Возвращаемый ответ может выглядеть так:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

SEC-WebSocket-Accept здесь генерируется SEC-WebSocket-Key в клиентском запросе. В частности, SEC-WebSocket-Key и строки «258Eafa5-E914-47Da-95CA-C5AB0DC85B11», переданные клиентом, связаны. Затем используйте алгоритм SHA1, чтобы найти его значение HASH.

Наконец, base64 кодирует хеш-значение.

После того, как сервер вернет Sec-WebSocket-Accept, клиент сможет его проверить, и весь процесс рукопожатия будет завершен.

формат сообщения webSocket

Причина использования webSocket заключается в том, что клиент и сервер могут отправлять сообщения в любое время и в любом месте. Это магия веб-сокетов. Так в каком формате отправляется сообщение? Давайте посмотрим поближе.

Сообщения, которыми обмениваются клиент и сервер, передаются в виде кадров. Формат кадра следующий:


      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-------+-+-------------+-------------------------------+
     |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
     |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
     |N|V|V|V|       |S|             |   (if payload len==126/127)   |
     | |1|2|3|       |K|             |                               |
     +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
     |     Extended payload length continued, if payload len == 127  |
     + - - - - - - - - - - - - - - - +-------------------------------+
     |                               |Masking-key, if MASK set to 1  |
     +-------------------------------+-------------------------------+
     | Masking-key (continued)       |          Payload Data         |
     +-------------------------------- - - - - - - - - - - - - - - - +
     :                     Payload Data continued ...                :
     + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
     |                     Payload Data continued ...                |
     +---------------------------------------------------------------+

MASK указывает, закодировано ли сообщение, поскольку сообщение исходит от клиента, оно должно быть MASK 1. Если клиент отправляет на сервер сообщение, MASK не равно 1, клиент и сервер должны разорвать соединение. Но сервер отправляет сообщение на клиентский конец, поле MASK настраивать не нужно.

RSV1-3 являются расширенными полями и могут быть проигнорированы.

код операции указывает, как интерпретировать поле полезной нагрузки. Полезная нагрузка — это фактическое сообщение, которое необходимо доставить. 0x0 означает продолжение, 0x1 означает текст, 0x2 означает двоичный файл, а остальные — контрольные поля.

FIN указывает, является ли это последним кадром сообщения. Если он равен 0, это означает, что для сообщения имеется больше кадров. Если он равен 1, это означает, что кадр является последней частью сообщения, и сообщение можно обработать.

Зачем нужно поле Payload len? Потому что нам нужно знать, когда перестать получать сообщения. Следовательно, поле, представляющее полезную нагрузку, требуется для выполнения специальной обработки сообщения.

Как анализировать полезную нагрузку? Это сложнее.

  1. Сначала прочитайте 9-15 бит, проанализируйте его как целое число без знака. Если меньше 125, то это длина полезной нагрузки, конец. Если 126, то переходим ко второму шагу. Если 127, то переходим к третьему шагу.
  2. Прочитайте следующие 16 бит, затем разбирайте его как целое число без знака, конец.
  3. Прочитайте следующие 64 бита. Разрешит его в целые числа символов. Заканчивать.

Если установлена ​​маска, то считываются следующие 4 байта, что составляет 32 бита. Это ключ маскировки. Когда данные считаны, мы получаем закодированную полезную нагрузку: ENCODED и ключ MASK. Для декодирования логика следующая:

var DECODED = "";
for (var i = 0; i < ENCODED.length; i++) {
    DECODED[i] = ENCODED[i] ^ MASK[i % 4];

FIN можно использовать вместе с кодом операции для отправки длинных сообщений.

FIN=1 означает, что это последнее сообщение. 0x1 указывает на текстовое сообщение, 0x2 — это 0, указывает на двухсетевое сообщение, а 0x0 указывает на то, что сообщение не закончилось, поэтому 0x0 обычно используется с FIN=0.

Расширения и подпротоколы

Во время процесса рукопожатия между клиентом и сервером на основе стандартного протокола веб-сокета клиент также может отправлять расширения или подпротоколы. В чем разница между этими двумя?

Прежде всего, оба они устанавливаются через заголовки HTTP. Но между ними все же есть большая разница. Расширения могут управлять WebSocket и изменять полезную нагрузку, в то время как подпротоколы только определяют структуру полезной нагрузки, но не изменяют ее.

Расширения необязательны, в то время как подпротоколы необходимы.

Вы можете думать о расширениях как о сжатии данных, оно сжимает или оптимизирует данные на основе веб-сокета, что может сделать отправляемое сообщение короче.

А подпротоколы представляют формат сообщения, например, использование мыла или wamp.

Подпротокол — это протокол, разработанный на основе протокола WebSocket. Он в основном используется для обработки конкретных сценариев. Это более строгая спецификация, установленная поверх протокола WebSocket.

Например, когда клиент запрашивает сервер, он помещает соответствующий протокол в заголовок Sec-WebSocket-Protocol:

GET /socket HTTP/1.1
...
Sec-WebSocket-Protocol: soap, wamp

Сервер будет поддерживать тип, сделает соответствующий возврат, например:

Sec-WebSocket-Protocol: soap

Суммировать

В этой статье объясняется особый формат взаимодействия сообщений WebSocket.Вы можете видеть, что многие мощные протоколы состоят из самых простых структур.

Эта статья была включена вWoo Woo Floyd Press.com/07-Web Soc для…

Самая популярная интерпретация, самая глубокая галантерея, самые краткие уроки и множество трюков, о которых вы не знаете, ждут вас!

Добро пожаловать, чтобы обратить внимание на мой официальный аккаунт: «Программируйте эти вещи», разбирайтесь в технологиях, лучше поймите себя!