Веб-сокет HTML5 (теория I)

внешний интерфейс сервер API WebSocket

* Сначала пригласите соседей ТА:*

http: без гражданства, на основеtcpответ на запросприкладной уровеньпротокол (A: Ой, ты меня угостил ужином в прошлый раз? B: Я думаю об этом, ты угостил тебя ужином в прошлый раз)tcp: Ориентирован на соединение, обеспечивая высокую надежность (без потери данных, без нарушения данных, без ошибок данных, без повторного поступления данных)транспортный уровеньпротокол. (Смотрите, военный парад, такой аккуратный и стройный)

Зачем вводить Websocket:

Введение в RFC: цель этого протокола — решить проблему, связанную с тем, что программы на основе браузера должны инициировать несколько HTTP-запросов и долгосрочный опрос, когда им нужно извлекать ресурсы.

длинный опрос (long polling): после того, как клиент отправляет запрос, сервер получает соединение и, если есть сообщение, возвращает ответ клиенту. Если сообщения нет, ответ не возвращается. После этого клиент снова отправляет запрос, повторяя последнее действие.

Как видно из вышеизложенного, характеристикой протокола http является то, что сервер не может активно связываться с клиентом, а может быть инициирован только клиентом. Его пассивный характер указывает на то, что когда двусторонняя связь завершена, соединение необходимо держать открытым или соединение всегда открыто, что требует высокой скорости обработки или высокого параллелизма сервера, что очень ресурсоемко.

В это время появился Websocket.

Что такое веб-сокет:

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

Да, обратите внимание на:двусторонняя связь

После подключения Websocket клиент может активно отправлять сообщения на сервер, а сервер также можетАктивно отправляйте сообщения клиентам. Например: информация о бронировании билетов, в дополнение к нашей просьбе спросить, как билет, конечно, мы надеемся, что если появятся какие-либо новые новости, вы можете напрямую уведомить нас.

Его особенности:

(1) Протокол HTTP используется на этапе рукопожатия, а порты по умолчанию — 80 и 443.

(2) Он основан на протоколе TCP и относится к прикладному уровню как протокол http.

(4) Можно отправлять текст, а также двоичные данные.

(5) Нет ограничений на одно и то же происхождение, клиент может общаться с любым сервером

(6) Идентификатор протокола — ws (если зашифровано, wss), например, ws://localhost:8023.

Проще говоря, протокол Websocket делится на две части: рукопожатие и передача данных.

API веб-сокета:

Это относится к клиентскому API.

Конструктор WebSocket

  1. 通过调用WebSocket构造函数来创建一个WebSocket实例对象,建立客户端与服务器的连接。

скопировать код
  1. const ws = new WebSocket('ws://localhost:8023');

скопировать код

События веб-сокета

  1. WebSocket 是纯事件驱动,通过监听事件可以处理到来的数据和改变的连接状态。服务端发送数据后,消息和事件会异步到达。

скопировать код
  • open:

    Когда сервер отвечает на запрос подключения WebSocket, запускается событие открытия. onopen — это функция обратного вызова ответа.

  • // 连接请求open事件处理:

    ws.onopen = e => {

        console.log('Connection success');

        ws.send(`Hello ${e}`);

    };

Если вы хотите указать несколько функций обратного вызова, вы можете использовать метод addEventListener.

  1. ws.addEventListener('open', e => {

  2.  ws.send(`Hello ${e}`);

  3. });

скопировать код

Когда срабатывает событие открытия, это означает, что фаза рукопожатия завершена. Сервер обработал запрос на подключение и готов к отправке и приему данных.

  • Message:

    Когда данные сервера будут получены, будет запущено событие сообщения, а onmessage — это функция обратного вызова ответа. следующим образом:

  1. // 接受文本消息的事件处理:

  2. ws.onmessage = e => {

  3.    const data = e.data;

  4.    if (typeof data === "string") {

  5.        console.log("Received string message ",data);

  6.    } else if (data instanceof Blob) {

  7.        console.log("Received blob message ", data);

  8.    }

  9. };

скопировать код

Данные сервера могут быть текстовыми или двоичными данными.Существует два типа Blob и ArrayBuffer.Перед чтением данных необходимо определить тип данных.

  • Error

    Ошибка вызовет событие ошибки, а onerror — это функция обратного вызова ответа, которая приведет к закрытию соединения.

  1. //异常处理

  2. ws.onerror = e => {

  3.    console.log("WebSocket Error: " , e);

  4.    handleErrors(e);

  5. };

скопировать код
  • Close

    Событие close запускается, когда соединение закрывается, что соответствует методу onclose.После закрытия соединения сервер и клиент больше не могут общаться.

Кадр пинга и фрейм pong определены в спецификации WebSocket, которые могут использоваться для повторного подключения пульса, запроса состояния сети и т. д., но в настоящее время браузеры только автоматически отправляют фреймы пинга вместо кадров пинга. (Если вам интересно, вы можете подробно проверить кадры пинга и понга)

  1. //关闭连接处理

  2. ws.onclose = e => {

  3.    const code = e.code;

  4.    const reason = e.reason;

  5.    console.log("Connection close", code, reason);

  6. };

скопировать код

Методы веб-сокета:

Объект WebSocket имеет два метода: отправить и закрыть.

  • send:

    После того, как клиент установит соединение с сервером, он может вызвать метод send для отправки сообщения.

  1. //发送一个文本消息

  2. ws.send("this is websocket");

скопировать код

Вызовите метод send() в обратном вызове события open для передачи данных:

  1. const ws = new WebSocket('ws://localhost:8023');

  2. ws.onopen = e => {

  3.    console.log('Connection success');

  4.    ws.send(`Hello ${e}`);

  5. };

скопировать код

Если вы хотите отправлять сообщения в ответ на другие события, вы можете оценить свойство readyState текущего веб-сокета. Далее мы поговорим о readyState.

  • close

    Метод close используется для закрытия соединения. После вызова метода close данные не могут быть отправлены. Метод close может передавать два необязательных параметра, код и причину, чтобы сообщить серверу, почему соединение разрывается.

  1. ws.close();

  2. //1000是状态码,代表正常结束。

  3. ws.close(1000, "Closing normally");

скопировать код

Свойства веб-сокета

  • состояние готовности:

Значение readyState представляет состояние соединения и является свойством только для чтения. Он имеет следующие четыре значения:

WebSocket.CONNECTING : Соединение установлено, но еще не установлено WebSocket.OPEN : Соединение установлено и сообщения могут быть отправлены WebSocket.CLOSING : Соединение находится в процессе закрытия рукопожатия WebSocket.CLOSED : Соединение закрыто или не открывается

В дополнение к вызову метода send в обратном вызове события open сообщения можно отправлять, оценивая значение readyState.

  1. function bindEventHandler(data) {

  2.    if (ws.readyState === WebSocket.OPEN) {

  3.        ws.send(data);

  4.    } else {

  5.        //do something

  6.    }

  7. }

скопировать код
  • буферизованная сумма:

    Когда клиент передает большой объем данных, браузер кэширует данные для вывода.Атрибут bufferedAmount может определить, сколько байтов двоичных данных не было отправлено и закончилась ли отправка.

  1. ws.onopen = function () {

  2.    setInterval( function() {

  3.        //缓存未满的时候发送

  4.        if (ws.bufferedAmount < 1024 * 5) {

  5.            ws.send(data);

  6.        }

  7.    }, 2000);

  8. };

скопировать код
  • протокол:

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

* Далее поговорим о процессе фазы рукопожатия.*

Когда мы создаем объект экземпляра Websocket для установления соединения с сервером,

  1. const ws = new WebSocket('ws://localhost:8023');

скопировать код

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

  1. GET /game HTTP/1.1

  2. Host: 10.242.17.102:8023

  3. Cache-Control: no-cache

  4. Upgrade: websocket

  5. Connection: Upgrade

  6. Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==

  7. Sec-WebSocket-Protocol: game

  8. Sec-WebSocket-Version: 10

  9. Origin: http://192.168.185.16

  10. Accept-Encoding: gzip, deflate, sdch

  11. Accept-Language: zh-CN,zh;q=0.8

скопировать код

Как видно из заголовка запроса, на самом деле это HTTP-запрос рукопожатия. В отличие от обычного http-запроса добавляется некоторая информация заголовка.

  • Поле «Обновление»: уведомите сервер о том, что теперь будет использоваться обновленный протокол — Websocket.

  • Sec-WebSocket-Key: это значение в кодировке Base64, которое случайным образом генерируется браузером и передается на сервер.Необходимо проверить, возможна ли связь через веб-сокет.

  • Sec_WebSocket-Protocol: определяемая пользователем строка, используемая для идентификации протокола, требуемого службой.

  • Sec-WebSocket-Version: уведомить версию протокола, используемую сервером.

Ответ сервера:

  1. 当服务器返回以下内容,就表示已经接受客户端请求啦,可以建立Websocket通信啦。

скопировать код
  1. HTTP/1.1 101 Switching Protocols

  2. Upgrade: websocket

  3. Connection: Upgrade

  4. Sec-WebSocket-Accept: SIEylb7zRYJAEgiqJXaOW3V+ZWQ=

скопировать код
  • Код состояния 101, указывающий, что протокол необходимо преобразовать

  • Обновление: уведомите клиента о том, что он собирается перейти на протокол Websocket.

  • Sec-WebSocket-Accept: Подтверждено сервером и зашифровано Sec-WebSocket-Key. Используется для доказательства того, что клиент и сервер могут обмениваться данными.

На этом этапе клиент и сервер успешно рукопожатие для установления соединения Websocket, и связь больше не использует фреймы данных HTTP, а использует фреймы данных, независимые от Websocket.


Вышеизложенное является основной теоретической главой протокола Websocket I. Добро пожаловать, друзья, чтобы передать (теоретическая глава II, фактическая боевая глава), учиться и накапливать вместе ~

——————————————————

Нажмите и удерживайте QR-код, следуйте Dazhuanzhuan FE