(Web Sockets) - это передовая технология, которая позволяет создавать интерактивное соединение между клиентом (браузером) и сервером для обмена сообщениями в режиме реального времени. Веб-сокеты, в отличие от HTTP, позволяют работать с двунаправленным потоком данных, что делает эту технологию совершенно уникальной. Давайте разберемся, как работает эта технология и чем она отличается от HTTP.

Как работает HTTP?

Схема обмена сообщениями по HTTP

Вы наверняка знаете, что такое HTTP (или HTTPS), поскольку встречаетесь с этим протоколом каждый день в своём браузере. Браузер постоянно спрашивает у сервера, есть ли для него новые сообщения, и получает их.

Вы также можете знать, что HTTP позволяет использовать разные типы запросов, такие как POST, GET или PUT, каждый из которых имеет своё назначение.

Как работают веб-сокеты?

Схема обмена сообщениями при использовании веб-сокетов

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

Веб-сокеты можно использовать, если вы разрабатываете:

  • приложения реального времени;
  • чат-приложения;
  • IoT-приложения;
  • многопользовательские игры.
Когда следует избегать использования веб-сокетов?

Практически никогда. Единственный минус - это несовместимость с некоторыми браузерами, но уже 95 % браузеров поддерживают веб-сокеты.

В некоторых случаях веб-сокеты вам всё же не понадобятся. Если вы создаёте простую CMS, вам вряд ли пригодится функциональность в режиме реального времени. Также не стоит использовать веб-сокеты в REST API, поскольку вам хватит таких HTTP-запросов, как GET, POST, DELETE и PUT.

Практические примеры

В примерах ниже для клиента используется JavaScript, а для сервера - Node.js. Примеры очень просты и вряд ли пригодятся на практике, но зато позволят разобраться в сути.

Веб-сокеты

Пример чата с веб-сокетом let ws = new WebSocket("ws://localhost:8080"); // выводим новые сообщения в консоль ws.onmessage = ({data}) => { console.log(data); } // отправляем сообщение ws.onopen = () => ws.send("Text");

Const WebSocket = require("ws"); // создаём новый websocket-сервер const wss = new WebSocket.Server({ port: 8080 }); // отправляем клиентам, когда функция clientValidator возвращает true. this - это wss. wss.broadcast = function(data, clientValidator = () => true) { this.clients.forEach(client => { if (clientValidator(client)) { client.send(data); } }); } wss.on("connection", ws => { // событие будет вызвано, когда клиент отправит сообщение ws.on("message", message => { // отправляем сообщение всем, кроме автора wss.broadcast(message, client => client !== ws); }); });

Вот иллюстрация работы веб-сокетов:

Демонстрация работы веб-сокетов

Эквивалент в HTTP

Так как HTTP должен постоянно проверять канал на наличие новых сообщений, можно использовать «грязную» проверку (dirty check) - подход, при котором клиент с заданной периодичностью (допустим, каждые 200 мс) проверяет наличие новых сообщений на сервере.

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

Краткая история веб-приложений реального времени

Интернет был построен на представлении о том, что забота браузера– запрос данных с сервера, а забота сервера – обслуживание этих запросов. Эта парадигма не подвергалась сомнению несколько лет. Но с появлением AJAX в 2005 году многие начали работать над созданием двунаправленных соединений.

Веб-приложения значительно увеличивались в размере. Сдерживающим фактором для их роста была традиционная модель HTTP. Чтобы преодолеть это, были созданы несколько стратегий, позволяющих серверам «проталкивать» (push) данные клиенту. Одной из наиболее популярных стала стратегия «длинного опроса» . Она подразумевает поддержание HTTP- соединения открытым до тех пор,пока у сервера есть данные для отправки клиенту.

Но все эти технологии приводят к перегрузке HTTP. Каждый раз, когда вы делаете запрос HTTP, набор заголовков и cookie передаются на сервер. Они накапливаются в большие массивы информации, которые нужно передать. Это увеличивает время ожидания, что может быть критично для равномерной работы приложения.

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

Как работают веб-сокеты

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

Браузер устанавливает соединение по веб-сокету при помощи «рукопожатия». Этот процесс начинается с отправки клиентом обычного запроса HTTP на сервер. В этот запрос включается заголовок Upgrade, который сообщает серверу, что браузер хочет установить соединение по веб-сокету.

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

GET ws ://websocket.example.com/ HTTP/1.1

Origin : http://example.com

Connection : Upgrade

Host : websocket.example.com

Upgrade : websocket

Замечание : URL-адреса веб-сокетов используют протокол ws . Также существует протокол wss для безопасных соединений, который является эквивалентом HTTPS.

Если сервер поддерживает протокол WebSocket, он сообщает об этом с помощью заголовка Upgrade в ответе.

HTTP /1.1 101 WebSocket Protocol Handshake

Connection : Upgrade

Upgrade : WebSocket

После того, как рукопожатие выполнено, первоначальное соединение HTTP заменяется соединением по веб-сокету, которое использует то же соединение TCP/IP . На этом этапе любая из сторон может начать отправку данных.

С помощью веб-сокетов можно передавать неограниченный объем информации без добавления данных, связанных с запросами (как в HTTP). Данные передаются через веб-сокет как сообщения, каждое из которых состоит из одного или большего количества фрагментов.

Чтобы убедиться, что сообщение будет правильно интерпретировано на стороне клиента, каждому фрагменту предшествуют от 4 до 12 байт данных о полезной нагрузке. Использование обмена сообщениями на основе фрагментов позволяет снизить объем дополнительных данных, что приводит к сокращению задержек.

Замечание : Стоит отметить, что клиент будет уведомлен о новом сообщении только, когда сервер передаст все его фрагменты.

Создаём демо-пример Создание приложения на основе веб-сокетов

Мы создадим простое приложение, которое соединяется с сервером по веб-сокету. Перед тем, как мы углубимся в детали API, нужно создать несколько файлов.

Посмотреть пример

Загрузить код

Посмотреть на CodePen

Создайте файл index.html и добавьте в него следующую разметку.

WebSockets Demo WebSockets Demo Connecting... Send Message Close Connection

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

Файл style.css , на который ссылается этот код, находится в архиве для загрузки. Далее создадим файл app.js и добавим в него следующий код.

window.onload = function() { // Получаем ссылки на элементы страницы. var form = document.getElementById("message-form"); var messageField = document.getElementById("message"); var messagesList = document.getElementById("messages"); varsocketStatus = document.getElementById("status"); varcloseBtn = document.getElementById("close"); // Остальной код из этой статьи будет добавляться ниже... };

Мы создали несколько переменных и инициализировали их ссылками на ключевые элементы страницы.

Открытие соединений

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

Скопируйте следующий код в файл app.js , чтобы создать новое соединение.

// Создаём новый объект WebSocket. varsocket = new WebSocket("ws://echo.websocket.org");

После того, как соединение установлено, возникнет событие open объекта WebSocket. Добавим обработчик события, который обновит статус элемента сообщением о том, что соединение установлено.

// Показываем сообщение «connected» при открытии веб-сокета. socket.onopen = function(event) { socketStatus.innerHTML = "Connected to: " + event.currentTarget.url; socketStatus.className = "open"; };

Также мы добавляем класс open элементу .

Обработка ошибок

Обработка ошибок осуществляется через событие error . Добавьте следующий код, который будет записывать ошибки в консоль.

// Обработка возникающих ошибок. socket.onerror = function(error) { console.log("WebSocket Error: " + error); };

Отправка сообщений

Чтобы отправить сообщение по веб-сокет, нужно вызвать метод send() объекта WebSocket, передав ему данные для отправки.

socket.send(data);

Можно отправлять как текст, так и двоичные данные. В нашем приложении нужно передавать содержимое текстового поля на сервер при отправке формы. Чтобы сделать это, надо определить обработчик события отправки формы.

Добавьте следующий код в файл app.js .

// Отправка сообщения при отправке формы form.onsubmit = function(e) { e.preventDefault(); // Получение сообщения из текстового поля. var message = messageField.value; // Отправка сообщения по веб-сокету. socket.send(message); // Добавление сообщения в список сообщений. messagesList.innerHTML += "Sent:" + message + ""; // Очистка текстового поля. messageField.value = ""; return false; };

При отправке формы приведенный выше код получит сообщение из messageField и отправит его через веб-сокет. Затем сообщение добавляется в messagesList и отображается на экране. После этого значение messageField очищается, чтобы пользователь мог ввести новое сообщение.

Получение сообщений

При получении сообщения вызывается событие message . Оно включает в себя свойство data , которое можно использовать для доступа к содержимому сообщения.

Нам нужно создать обработчик события, который будет вызываться при получении нового сообщения. Он должен получать сообщение от события и отображать его в messagesList .

Чтобы добиться этого, скопируйте следующий код в файл app.js .

// Обработка сообщений, отправленных сервером. socket.onmessage = function(event) { var message = event.data; messagesList.innerHTML += "Received:" + message + ""; };

Закрытие соединений

Когда вы закончите работу с веб-сокетом, нужно разорвать соединение, используя метод close() .

После того, как соединение будет разорвано, браузер вызовет событие close . Добавление обработчика события close позволит выполнить любую «уборку», которая потребуется.

Теперь нам нужно обновить статус соединения при его разрыве. Добавьте следующий код в файл app.js :

// Показываем сообщение «disconnected», когда соединение разорвано. socket.onclose = function(event) { socketStatus.innerHTML = "Disconnectedfrom WebSocket."; socketStatus.className = "closed"; };

Чтобы завершить приложение, нужно добавить обработчик события, который будет вызываться при нажатии кнопки «Close Connection». Он должен вызывать метод close() объекта WebSocket.

// Закрываем соединение при нажатии кнопки «close» closeBtn.onclick = function(e) { e.preventDefault(); // Закрываем веб-сокет. socket.close(); return false; };

Наше приложение готово!

Откройте файл index.html в браузере и попробуйте отправить несколько сообщений. Вы увидите, что сервер отправляет сообщения обратно.

Мониторинг трафика веб-сокета с помощью инструментов для разработчиков в Chrome


«Инструменты разработчика», доступные в браузере Google Chrome включают в себя средства для мониторинга трафика. Чтобы использовать этот инструмент:

  • Откройте «Инструменты разработчика».
  • Перейдите на вкладку Network.
  • Кликните по записи, соответствующей вашему соединению по веб-сокету.
  • Перейдите на вкладку Frames.

Эти инструменты предоставляют общую информацию о данных, переданных через соединение.

WebSocket на сервере

В этой статье мы сфокусировали внимание на том, как использовать веб-сокеты на стороне клиента. Если вы хотите создать собственный сервер WebSocket, существует множество библиотек, которые могут в этом помочь. Одна из наиболее популярных – socket.io , библиотека Node.JS.

Другие библиотеки:

  • C++: libwebsockets ;
  • Erlang: Shirasu.ws ;
  • Java: Jetty ;
  • Node.JS: ws ;
  • Ruby: em-websocket ;
  • Python: Tornado , pywebsocket ;
  • PHP: Ratchet , phpws .
Поддержка браузерами

Веб-сокеты поддерживаются практически во всех современных браузерах. Единственными исключениями являются Android- браузеры и Opera Mini.

Веб-сокеты (WebSockets), возможно, самое интересное нововведение в веб-техноло­гиях со времен появления "Aсинxpoннoгo JavaScript и XML"(AJAX). Они стали популярными с выходом HTML5 и поддерживаются множеством веб-фреймворков.

Однако потребовалось немало времени для создания стабильной и совместимой спе­цификации веб-сокетов.

Модель протокола передачи гипертекста (НТТР) была спроектирована задол­го до того, как стал популярен Интернет, она основывается на простых специфи­кации и дизайне. В традиционной модели НТТР клиент открывает соединение с сервером прикладной части, отправляет HTTP-запрос типа GET, POST, PUT или DELETE, а HTTP-сервер возвращает соответствующий ответ.

Традиционная модель НТТР была обременительной практически для любого приложения, выходящего за пределы простой модели данных "получить и отправить контент ". Представьте себе клиент приложения для интерактивной переписки, в ко­тором участники могут отправлять сообщения в любом порядке и сотни участников могут общаться одновременно.

Для подобных целей стандартный подход "запрос-ответ " налагает слишком сильные ограничения. Первыми попытками обойти эти ограничения стали AJAX и Comet. Оба были основаны на так называемых длинных опросах: открытии НТТР-соединения и поддержании его в активном состоянии (сохранении соединения открытым) посредством незавершения отправки ответа.

С помощью веб-сокетов клиент может создать "сырой " сокет для сервера и осу­ществлять полнодуплексную связь. Поддержка веб-сокетов была введена в JSR-356 .

Пакет javax.websocket и его серверный подпакет содержат все относящиеся к веб­ сокетам классы, интерфейсы и аннотации.

Чтобы реализовать веб-сокеты на платформе Java ЕЕ, вам необходимо создать класс конечной точки с методами жизненного цикла веб-сокета, как показано ниже:

// Пример конечной точки package com.devchronicles.websockets; public class HelloEndpoint extends Endpoint { @Override public void onOpen(final Session session, EndpointConfig config) { session.addMessageHandler(new MessageHandler.Whole() { @Override public void onMessage(String msg) { try { session.getBasicRemote().sendText("Hello " + msg); } catch (IOException e) { } } }); } }

// Пример конечной точки

public class HelloEndpoint extends Endpoint {

@Override

public void onOpen (final Session session , EndpointConfig config ) {

session . addMessageHandler (new MessageHandler . Whole () {

@Override

public void onMessage (String msg ) {

try {

} catch (IOException e ) { }

} ) ;

Класс Endpoint предоставляет три метода жизненного цикла: onOpen , onClose и onError . Расширяющий его класс должен реализовать как минимум метод onOpen .

Вы можете развернуть конечную точку двумя способами: с помощью конфигу­рации или программными средствами.

Чтобы выполнить развертывание кода ваше при­ложение должно вызвать следующее:

ServerEndpointConfig.Builder.create(HelloEndpoint.class, "/hello").build();

ServerEndpointConfig . Builder . create (HelloEndpoint . class , "/hello" ) . build () ;

Развернутый веб-сокет доступен на ws://://hello . Од­нако лучше использовать конфигурацию с помощью аннотации. При этом та же конечная точка становится кодом который приводится ниже:

// Пример конечной точки с аннотациями package com.devchronicles.websockets; @ServerEndpoint("/hello") public class HelloEndpoint { @OnMessage public void onMessage(Session session, String msg) { try { session.getBasicRemote().sendText("Hello " + msg); } catch (IOException e) { } } }

// Пример конечной точки с аннотациями

package com . devchronicles . websockets ;

@ServerEndpoint ("/hello" )

public class HelloEndpoint {

@OnMessage

public void onMessage (Session session , String msg ) {

try {

session . getBasicRemote () . sendText ("Hello " + msg ) ;

} catch (IOException e ) { }

Такой подход позволяет вам использовать аннотации, придерживаясь подхода простых Jаvа-объектов в старом стиле (POJO ), поскольку вы не расширяете базо­вый класс. У аннотированной конечной точки те же методы жизненного цикла, что и в первом примере кода, но она вводит дополнительный метод жизненного цикла onMessage .

Вместо реализации OnOpen и добавления обработчика onMessage в основанном на аннотациях подходе достаточно реализовать аннотированный метод жизненного цикла onMessage . Вы можете аннотировать с помощью @ОnМеssаgе несколько методов, чтобы получать различные типы данных, такие как String или ByteBuffer для дво­ичных данных.

Реализация веб-сокета со стороны клиента зависит от используемого веб-фрейм­ворка. Как бы то ни было, в следующем фрагменте показана простая версия на языке JavaScript :

var webSocket = new WebSocket("ws://127.0.0.1:8080/websockets/hello"); webSocket.send("world");

Что такое WebSocket. Что лучше — Веб-сокеты или AJAX?

5 (100%) 3 votes

WebSocket (Веб-сокет ) — это протокол полнодуплексной связи поверх TCP-соединения. То есть с помощью этого протокола можно передавать и принимать сообщение одновременно. Он позволяет в режиме реального времени обмениваться сообщениями между браузером и сервером.

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

Браузер — веб-сервер. Как это работает и что нужно менять?

Для веб-разработчиков всегда было проблемой получение реакции браузера на события, который происходит на сервере. HTTP-протокол имеет некие недостатки, и его, наверное, критиковали все разработчики. Один из таких недостатков — это проблема постоянного соединения с сервером. Реализация HTTP-протокола не предполагала подобного рода взаимодействия. Например, если мы хотим получить данные с сервера в браузер, то нужно сделать очередной запрос к серверу, и это предполагает перезагрузку страницы. То есть, если открыли сайт в браузере, загрузили страницу, просмотрели, и к этому времени на сервере изменилось данная страница, то нам нужно перезагрузить страницу, чтобы получить изменение.

Есть довольно большое количество задач, где нам нужно получить асинхронность используя HTTP-протокол. То есть, если на сервер будут изменение, то нужно получить эти изменение в браузере, без перезагрузки. Один из таких примеров — это чат, где люди общаются, и когда один другому отправляет сообщения, то сообщения видна получателю моментально, без перезагрузки страницы. Раньше, создание такого вида приложение было нелегко, находились разные степени интерпретации, которые имитировали push-действия сервера. Один из таких примеров — это организованные на клиенте фреймов, которые перезагружаются раз в секунду и отправляют запросы на сервер.

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

А теперь давайте поговорим об AJAX . Когда объект XMLHTTPRequest появилось в браузерах, положение немного улучшилось. В данном случае мы можем взаимодействовать с сервером по схеме Long Polling . Ниже по пунктам описан суть данной схемы:

  • Клиент (браузер) отправляет запрос на сервер,
  • Соединение не закрывается и клиент ожидает наступления события,
  • Когда события происходит клиент получает ответ на свой запрос,
  • Клиент тут же отправляет новый запрос.

С помощью этого подхода мы получаем асинхронные запросы к серверу, а ответы обрабатываются с помощью функциями обратного вызова. Но и этот подход имеет некоторые недостатки. Главный недостаток этого подхода заключаться в том, что здесь сервер и серверные события не являются инициатором взаимодействия.

Не так давно появилось новый протокол, у которого нет таких недостатков, которые выше мы перечислили. Новая технология WebSockets представляет собой реализацию протокола полнодуплексной связи поверх TCP-соединения.

Почему WebSockets? Плюсы и минусы протокола ws

Используя технологию Веб-Сокеты нам нужно забыть привычную систему взаимодействие в мире WWW. Нам нужно забить стандартный модель HTTP-протокола — «запрос/ответ на запрос». В рамках технологии Веб-Сокетов браузер и сервер в любой момент могут отправлять и принимать данные, то ест они становится равными участниками.

WebSocket устанавливает одно единственное соединение клиента с сервером. Для работы с WebSockets обе стороны (клиент и сервер) должны поддерживать данную технологию. Все новые браузеры поддерживают протокол WS, а серверная часть реализуется разработчиком. Когда сервер и клиент готовы к «бою», сервер и клиент могут отправлять через Веб-Сокеты текстовые текстовые сообщение. Передача и прием данных происходит сразу же, данная технология создает двунаправленные каналы связи.

Так как соединение с клиентом и сервером не закрывается (он держится открытым постоянно), это позволяет избежать передачи лишних данных (HTTP-заголовки). В стандарте WebSockets нет никаких ограничение по количеству открытых соединение и по очередностью запросов.

В этом уроке мы узнали — какие способы есть для асинхронных запросов на сервер, что такое WebSocket и какие преимущества у него есть по сравнению с AJAX и HTML фреймов. В следующем уроке мы начнём работать с WebSocket на Node.js, более подробно будем рассматривать данную технологию в действие и напишем чат на Веб-Сокетов и Node.js. Полный список уроков Node.js вы найдете .

Всем известный протокол HTTP является изначально синхронным, то есть построенным по модели «запрос - ответ». WebSocket - это серьезное расширение HTTP, которое позволит приложениям (в том числе и играм) поддерживать многопользовательское взаимодействие в режиме реального времени. Благодаря ему не станет клиента и сервера с фиксированными ролями, а появятся два равноправных участника обмена данными. Каждый при этом работает сам по себе, и когда надо отправляет данные другому. Вторая сторона отвечает по мере необходимости, и только если эта необходимость возникнет.

WebSocket - протокол полнодуплексной двунаправленной связи поверх TCP-соединения, предназначенный для обмена сообщениями между браузером и веб-сервером в режиме реального времени. Программисты и ранее пытались решить проблему «равноправия» между сервером и клиентом. Они экспериментировали с двунаправленной связью, используя запросы XMLHttpRequest. Но это было очень медленно, так как каждый раз приходилось создавать новое TCP-соединение для каждого сообщения.
В отличие от XMLHttpRequest WebSockets устанавливает одно TCP-соединение и подтверждает, что сервер может общаться с WebSocket, делая специальные проверки, после чего сервер и клиент могут отправлять текстовые сообщения через установленное соединение при необходимости, в результате чего связь становится быстрее. Соединение постоянно держится открытым, но не передаёт лишних HTTP заголовков. При этом в веб-сокетах нет ограничений на количество соединений.

В настоящее время в World Wide Web Consortium (W3C) происходит стандартизация API Web Sockets, а в Internet Engineering Task Force (IETF) находится на утверждении стандарт протокола Web Socket.
В той или иной мере WebSocket поддерживается в следующих браузерах:

  • Google Chrome (начиная с версии 4.0.249.0);

  • Apple Safari (начиная с версии 5.0.7533.16);

  • Mozilla Firefox (начиная с версии 4);

  • Opera (начиная с версии 10.70 9067);

  • Разные версии браузеров поддерживают разные версии протоколов. Причем само развитие протокола позволяет предполагать, что со временем он может измениться несовместимым образом. Однако, маловероятно что изменится WebSocket API. Как работает протокол? Как только страница сайта решила, что она хочет открыть WebSocket на сервер, она создает специальный javascript-объект. Все начинается так же как в обычном HTTP-запросе. Браузер подключается по протоколу TCP на 80-й порт сервера, но дает немного необычный GET-запрос, и, если сервер поддерживает WebSocket, то он отвечает. Если браузер это устраивает, то он просто оставляет TCP-соединение открытым. Все - установление связи совершено, канал обмена данными готов.
    Как только одна сторона хочет передать другой какую-то информацию, она отправляет дата-фрейм следующего вида:
    0x00, , 0xFF
    То есть просто строка текста - последовательность байт, к которой спереди приставлен нулевой байт 0x00, а в конце - 0xFF. Без заголовков и метаданных. Что именно отправлять, разработчики полностью оставили на усмотрение разработчиков сайтов: XML, JSON, простой текст.

    С помощью протокола WebSockets так же можно передавать и бинарные данные, в смысле картинки. Для них используется другой дата-фрейм следующего вида:
    0x80, ,
    «Один или несколько байт» - очень хитрый способ указания длины тела сообщения. Чтобы не создавать ограничений на длину передаваемого сообщения и в тоже время не расходовать байты нерационально, разработчики протокола использовали следующий алгоритм. Каждый байт в указании длины рассматривается по частям: самый старший бит указывает, является ли этот байт последним (0) или же за ним есть другие (1), а младшие 7 битов содержат собственно данные.
    Соответственно, как только получается признак бинарного дата-фрейма 0x80, то берется следующий байт и откладывается его в отдельную «копилку», потом на следующий байт - если у него установлен старший бит, то переносится и его в «копилку». И так далее, пока вам не встретится байт со старшим битом - 0. Это означит что этот байт - последний в указателе длины. Он также складывается в «копилку». Теперь из всех байтов в «копилке» убираются старшие биты и соединяется в единое целое остаток. Вот это и будет длина тела сообщения.
    КПД такого протокола стремится к 95%. Разница будет особенно заметна, если делать частый обмен небольшими блоками данных. Скорость обработки также стремится к скорости чистого TCP-сокета - ведь все уже готово - соединение открыто - всего лишь байты переслать.

    Нюансы протокола У протокола есть свои плюсы и минусы. Причем первых существенно больше.

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

    Стандартность , которая устранит потребность в целом ряде технологий: Comet и все что накручено поверх него (Bayuex, LongPolling, MultiPart и так далее), работающее на хаках, а не стандартах.

    Время жизни канала - WebSockets не имеют ограничений на время жизни в неактивном состоянии. Это значит, что больше не надо периодически обновлять соединение, т.к. его не вправе закрывать прокси-сервера. Значит, соединение может висеть в неактивном виде и не требовать ресурсов. Правда, на сервере будут забиваться TCP-сокеты. Для этого достаточно использовать хороший мультиплексор, и нормальный сервер легко потянет до миллиона открытых коннектов.

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

    Кросс-доменные приложения - о граничения в протоколе вводятся не по принципу «из-того-же-источника», а из «разрешенного-источника», и определяются не на клиенте, а на сервере.

    Еще одна особенность: в качестве единственной разрешенной кодировки выбрана UTF-8. Теперь о минусах.

    В конце ноября 2010 Адам Барт (Adam Barth) опубликовал результаты исследования надежности WebSocket. По его результатам выяснилось, что в случае использования прозрачных прокси-серверов возможна подмена кеша передаваемых данных. То есть пользователи вместо реальных данных могут получать версию данных от злоумышленника. Проблема оказалась довольно серьезной. В результате разработчики Firefox и Opera объявили, что до устранения проблем в будущих версиях их браузеров поддержка WebSocket будет закрыта, хотя они и оставили возможность их включить.
    Отметим особую роль разработчиков Opera, которые создали Opera"s WebSockets testsuite. Этот тест охватывает как сам протокол, так и API, пытаясь проверить все аспекты спецификаций, включая обработку ошибок и непредвиденного поведения. Было найдено большое количество багов и несоответствий в спецификациях. Отзыв об этом был отправлен рабочей группе, работающей со спецификациями.

    Возникают у Websockets проблемы и с антивирусами. Так в одном из проектов, переводимых на этот протокол, выяснилось, что все пользователи, кто использовал антивирус Avast в дефолтной конфигурации, не могли нормально работать с приложением. В Avast по умолчанию включен режим так называемого «Вэб-экрана», который решил, что Websocket протокол плохой, и молча «резал» его.

    Кому нужен этот протокол? WebSocket крайне полезен для тех разработчиков, кто создает:
    - веб-приложения, с интенсивным обменом данными, требовательные к скорости обмена и каналу;
    - приложения, следующие стандартам;
    - «долгоиграющие» веб-приложения;
    - комплексные приложения с множеством различных асинхронных блоков на странице;
    - кросс-доменные приложения.
    На протоколе WebSocket создано уже достаточно много приложений. Самое известные – это, наверное, разработки компании Kaazing, компания, которая давно ориентируется на WebSocket. Компания внедрила технологию, которая помогает выводить меняющиеся финансовые данные, поступающих извне. Одно из таких постоянно обновляет котировки фондового рынка. Резюме Очень скоро придет эра HTML 5 приложений. Для пользователей это означает еще больше интерактива и новых возможностей, в первую очередь, благодаря технологии Websockets. Мы надеемся, что эта технология получит очень широкое распространение. И как в свое время несколько лет прошло под эгидой AJAX, так теперь, через год-другой мы будем слышать отзывы о внедрении WebSockets повсеместно.