Технология WebSocket

  Технология WebSocket позволяет Web-странице (её скрипту) установить и использовать постоянный двухсторонний канал для обмена данными с Web-сервером. (Приложение, которое для этого используется на Web-сервере, естественно называют WebSocket-сервером.)
  В отличие, например, от метода fetch, в случае с WebSocket, речь идёт именно о постоянном и двухстороннем канале, и не только в рамках одного домена, и не по протоколу http(https). То есть:
  1. Инициатором передачи данных может быть как Web-страница, так и Web-сервер. (Естественно, что инициатором WebSocket-соединения может быть только скрипт какого-либо документа активной Web-страницы.)
  2. Множественный обмен данными осуществляется в рамках одного соединения.
      Не факт, что это однозначно хорошо. Ведь это логическое соединение, в то время как физическое соединение всё равно либо есть, либо его нет. При этом обмен данными по разовым логическим соединениям потребовал бы меньших издержек связанных с разработкой и реализацией WebSocket-серверов (например, соответствующих PHP скриптов).
      Понятно, что одно единое соединение требуется для того, чтобы инициатором передачи данных смог бы быть и Web-сервер. Однако вряд ли так уж это важно для обмена. Ведь клиентский скрипт всегда может легко организовать периодический опрос Web-сервера на наличие данных для клиента. А по протоколу ws(wss) такой опрос не сильно нагрузит сеть.
  3. Установленный канал является полнодуплексным.
      Это, как бы, преимущество постоянного соединения. Однако канал-то всё равно логический, а говорить о полнодуплексности физических каналов в данном случае не имеет ни какого смысла.
  Для WebSocket протокол http(https) был расширен, и это расширение было стандартизировано (RFC 6455) под аббревиатурой ws(wss).
  Надо отметить, что ws(wss) это именно расширение http(https), а не особый транспортный протокол.

  Протокол ws(wss), в отличие от базового http(https), предназначен для обмена данными (изначально множественного обмена не большими по объёму данными, по существу сообщениями) между Web-страницей и Web-сервером.
  Эти данные представляют собой последовательности из одного или нескольких фрагментов (кадров), и предназначены для скрипта, а не для браузера (как HTML-документ), поэтому они не обременены такой нагрузкой как заголовки, метаданные, информация о кодировке и формате и прочее.
  В каждом кадре ws(wss) содержится лишь информация о длине кадра, первый кадр содержит информацию о типе данных (двоичные или текстовые), последний кадр содержит флаг, о том, что он последний. Кроме того данные, по стандарту, всегда должны иметь кодировку utf-8 и (лучше) формат JSON.

  В ws(wss) любая из сторон - Web-сервер, или Web-страница может принудительно разорвать (закрыть) установленное соединение.
  В этом случае, этой стороной, контрагенту, отправляется кадр закрытия, который может содержать информацию о состоянии соединения и причине закрытия.
  В ответ на получение кадра закрытия, контрагент отправляет его кадр закрытия, предварив его (в зависимости от ситуации) ожидающими отправки данными.

  Благодаря таким своим особенностям, WebSocket в HTML5 очень эффективно экономит трафик и время.
  Речь идёт даже о многократном сокращении трафика (из-за http-заголовков) и времени обработки ws(wss) - запроса по сравнению с http(https).
  Однако есть очевидные издержки, и они связаны, в первую очередь, с необходимостью поддержки WebSocket-сервером постоянного соединения с клиентом. Очевидно, что если бы обмен данными по протоколу ws(wss) мог бы осуществляться по разовому соединению, то это во многом упростило бы создание разработчиками собственных WebSocket-серверов.
Теоретически, например, ни что не мешало бы передаче данных с помощью того же метода fetch по протоколу ws(wss), ведь в этом случае контрагентами также являются скрипты.
  Есть некоторые ограничения применения технологии WebSocket. Это:
  1. Серверное ПО должно быть приспособлено для реализации WebSocket-соединений и WebSocket-серверов, а хост-провайдер должен поддерживать WebSocket-соединения.
      Как правило, для высокопроизводительной работы WebSocket-соединений на сервере используются специальные фреймворки асинхронных приложений (например phpDaemon). Также и серверный Node.js поддерживает WebSocket.

      Надо заметить, что даже при поддержке серверным ПО протокола ws(wss), самостоятельная реализация WebSocket-сервера (например на PHP) связана с определёнными трудностями.
      Во-первых, необходимо обеспечить длительную (в идеале бесконечную) сессию WebSocket-сервера, а значит, фоновый (асинхронный) режим его выполнения.
      Во-вторых, необходимо предусмотреть возможные остановки и(или) перезагрузки самого Web-сервера.
  2. Прокси-серверы должны распознавать и поддерживать протоколы ws и wss.
  При всех своих недостатках, технология WebSocket является качественно новой парадигмой развития Web. Можно ожидать, что на основе WebSocket и того, что исторически получило название технологии AJAX, будет создана действительно прорывная Web-технология. В принципе может быть сменена сама идеология Web-хостинга. Можно предположить, что в хостинге, в целом, будет возрастать доля хостинга данных, по сравнению с хостингом документов.
  WebSocket
  WebSocket - Является интерфейсом к WebSocket-соединению.
  Экземпляр доступен:

  1. В выражении

      new WebSocket(Адрес[, Протоколы])

    где:
    • WebSocket - Имя функции конструктора.
    • Адрес - URI адрес Web-сервера (WebSocket--сервера), к которому необходимо подключиться, заданный в любом строковом формате.
        В этом адресе, вместо протокола http(https) должен быть указан протокол ws(wss) по той же схеме:
        ws: // хост [: порт] путь [? запрос] (по умолчанию- порт 80)
        wss: // хост [: порт] путь [? запрос] (по умолчанию- порт 443)
    • Протоколы - Массив названий субпротоколов для WebSocket-соединения.
        Названия субпротоколов задаются в любом строковом формате и должны соответствовать реестру IANA.
        В сущности сам субпротокол является строкой символов ASCII, которая обеспечивает взаимопонимание данных Web-страницы и Web-сервера в этом соединении.
        Сервер выберет из массива наиболее совместимый протокол.
        Название выбранного протокола будет находиться в значении свойства protocol.
      Любой новый экземпляр объекта WebSocket инициирует запрос браузера на новое WebSocket-соединение.
      Браузер отправляет по протоколу http(https) специфические заголовки, которые содержат запрос на поддержку сервером WebSocket-а. Если сервер, также по протоколу http(https), в ответных заголовках ответит утвердительно, то WebSocket-соединение устанавливается, и дальнейший обмен в рамках этого соединения будет происходить по протоколу ws(wss). (Вообще-то, использование протокола http(https) для установки WebSocket-соединения, мягко говоря, вызывает недоумение. Такой механизм в принципе лишает смысла использование WebSocket-а для разовых обменов данными между браузерным и серверным скриптами.)
  WebSocket свойства.
  binaryType - Содержит информацию о полученных двоичных данных, если данные не являются обычным текстовым сообщением.
  Значение имеет строковый формат.

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.binaryType[ = Значение]

Значения формата записи:

  • Экземпляр объекта WebSocket - Любой операнд значения со значением экземпляра объекта WebSocket.
  • . - Оператор доступа к свойству объекта.
  • binaryType - Ключевое слово.
  • = - Оператор присвоения. Ключевое слово в этом формате.
  • Значение - Формат полученных двоичных данных.
      Заданное в любом строковом формате одно из ключевых слов:
    • blob - Формат, с которым работает интерфейс Blob (умолчание).
    • arraybuffer - Формат, с которым работает интерфейс ArrayBuffer.
      Задавать значение свойства binaryType при отправке данных не обязательно, поскольку оно необходимо лишь для правильного представления данных в экземпляре объекта MessageEvent, переданного в функцию обратного вызова для обработки события message.
  bufferedAmount - Содержит количество байтов данных, которые были поставлены в очередь на передачу методом send, но еще не переданы в сеть.
  Значение имеет числовой формат.
  Значение не обнуляется при закрытии этого соединения.
  Каждый вызов метода send увеличивает это значение.

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.bufferedAmount

Значения формата записи:

  extensions - Содержит информацию о расширении полученных данных.
  Значение имеет строковый формат.
  Свойство extensions не поддерживается большинством браузеров.

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.extensions

Значения формата записи:

  onclose - Содержит функцию, которая должна быть вызвана, если соединение закрыто скриптом или разорвано Web-сервером.
  Событие onclose наступает и в результате (после) события error.
  Свойство readyState этого экземпляра объекта WebSocket, при наступлении события onclose, будет содержать значение 3.

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.onclose[= Функция]

Значения формата записи:

  onerror - Содержит функцию, которая должна быть вызвана, если, при соединении, произошла ошибка.
  Ошибка может возникнуть как в процессе установления соединения, так и во время его работы.

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.onerror[= Функция]

Значения формата записи:

  onmessage - Содержит функцию, которая должна быть вызвана, если через соединение получены данные от контрагента.

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.onmessage[= Функция]

Значения формата записи:

  onopen - Содержит функцию, которая должна быть вызвана, если соединение установлено.
  Создание экземпляра объекта WebSocket только инициирует процесс установления соединения, при этом может возникнуть ошибка.
  Поэтому событие error может возникнуть раньше события onopen.
  Свойство readyState этого экземпляра объекта WebSocket, при наступлении события onopen, будет содержать значение 1.

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.onopen[= Функция]

Значения формата записи:

  protocol - Содержит название субпротокола, который Web-сервер выберет для соединения.
  Значение имеет строковый формат.

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.protocol

Значения формата записи:

  readyState - Содержит информацию о состоянии соединения.
  Значение имеет числовой формат.

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.readyState

Значения формата записи:

  url - Содержит абсолютный адрес Web-сервера для соединения.
  Значение имеет строковый формат.

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.url

Значения формата записи:

  WebSocket методы.
  addEventListener - Устанавливает функцию обработчик событий для соединения.
  Возвращает значение undefined.

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.addEventListener(Событие, Функция, false)

Значения формата записи:

  • Экземпляр объекта WebSocket - Любой операнд значения со значением экземпляра объекта WebSocket.
  • . - Оператор доступа к методу объекта.
  • addEventListener - Ключевое слово.
  • ( - Оператор группировки. Ключевое слово в этом формате.
  • Событие - Имя события, предусмотренного для объекта WebSocket, заданное в любом строковом формате.
  • Функция - Любой операнд значения со значением функция.
      Значением первого аргумента этой функции всегда является экземпляр объекта ErrorEvent обрабатываемого события.
      Одна функция-обработчик устанавливается методом addEventListener только один раз и повторные вызовы метода для этой же функции не имеют значения.
      Однако другие функции могут быть установлены соединению методом addEventListener для этого же события, причем выполняться, в случае возникновения события, они будут в том же порядке, как записаны в скрипте.
      Если же обработчики для этого соединения и этого события установлены методом addEventListener в разных скриптах, то порядок их выполнения не предсказуем.
      Если функция-обработчик вернёт значение false, то браузер не будет выполнять действия, предусмотренные для этого события по умолчанию.
  • false - Логическое значение.
  • , - Оператор группировки. Ключевое слово в этом формате.
  • ) - Оператор группировки. Ключевое слово в этом формате.
  close - Закрывает соединение.
  Возвращает значение undefined.
  При закрытии соединения, из-за ошибки в значении аргументов код и(или) причина, может возникнуть событие error.
  Следствием вызова метода close всегда является событие close.

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.close([Код[, Причина]])

Значения формата записи:

  dispatchEvent - Инициализирует возникновение заданного события в этом соединении.
  Возвращает значение undefined.
  Инициализированное событие не происходит на самом деле, но инициализация приводит к вызову его обработчика.

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.dispatchEvent(Событие)

Значения формата записи:

  removeEventListener - Отменяет функцию обработчик событий установленную методом addEventListener для соединения.
  Возвращает значение undefined.

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.removeEventListener(Событие, Функция, false)

Значения формата записи:

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

Формат записи в коде скрипта:

  • Экземпляр объекта WebSocket.send(Данные)

Значения формата записи: