Технология websockets. Введение в веб-сокеты. И как это работает

Что такое 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 вы найдете .

Веб-сокеты

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

Если вы создаете веб-приложение, в котором требуется серьезное двустороннее взаимодействие браузера с веб-сервером, лучшим подходом к его реализации (не прибегая к помощи Flash) будет, возможно, использование объекта XMLHttpRequest. В зависимости от типа создаваемого приложения этот подход может работать так, как требуется. Но здесь существует и достаточное количество возможных проблем.

Прежде всего, объект XMLHttpRequest не очень хорошо подходит для быстрого обмена множественными сообщениями (например, в чате). Потом, в нем нет возможности связать один вызов с другим, поэтому при каждом новом запросе от веб-страницы сервер должен вычислять с самого начала, кому эта страница принадлежит. Поэтому уровень сложности кода для обработки ряда связанных запросов от веб-страницы может очень быстро вырасти до практически нереализуемой.

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

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

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

Получение доступа к веб-сокетам

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

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

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

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

Чтобы дать вам представление о масштабе сервера веб-сокетов, рассмотрите некоторые из задач, которые сервер сокетов должен выполнять:

    составить "словарь" сообщений, иными словами, решить, какие типы сообщений являются допустимыми, а какие нет;

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

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

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

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

Простой клиент веб-сокетов

С точки зрения веб-страницы функциональность веб-сокетов легко понять и использовать. Первый шаг - это создать объект WebSocket и передать ему URL. Код для этого подобен следующему:

Var socket = new WebSocket("ws://localhost/socketServer.php");

Строка URL начинается с текста ws://, который идентифицирует подключение типа веб-сокет. Этот URL указывает файл веб-приложения на сервере (в данном случае это сценарий socketServer.php).

Стандарт веб-сокетов также поддерживает URL, которые начинаются с текста wss://, что указывает на требование использовать безопасное, зашифрованное подключение (точно так же, как и при запросе веб-страницы указывается URL, начинающийся с https:// вместо http://).

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

Само обстоятельство создания объекта WebSocket понуждает страницу пытаться подключиться к серверу. Дальше надо использовать одно из четырех событий объекта WebSocket: onOpen (при установлении подключения), onError (когда возникает ошибка), onClose (при закрытии подключения) и onMessage (когда страница получает сообщение от сервера):

Socket.onopen = connectionOpen; socket.onmessage = messageReceived; socket.onerror = errorOccurred; socket.onopen = connectionClosed;

Например, в случае успешного подключения неплохо бы отправить соответствующее подтверждающее сообщение. Такое сообщение доставляется с помощью метода send() объекта WebSocket, которому в качестве параметра передается обычный текст. Далее приведена функция, которая обрабатывает событие onopen и отправляет сообщение:

Function connectionOpen() { socket.send("UserName:[email protected]"); }

Предположительно, веб-сервер получит это сообщение и даст на него ответ.

События onError и onClose можно использовать для отправки извещений посетителю веб-страницы. Но безоговорочно самым важным является событие onMessage, которое срабатывает при получении новых данных от сервера. Опять же, код JavaScript для обработки этого события не представляет никаких сложностей - мы просто извлекаем текст сообщения из свойства data:

Function messageReceived(e) { messageLog.innerHTML += "

Если веб-страница решит, что вся ее работа выполнена, она может закрыть подключение, используя метод disconnect() :

Socket.disconnect();

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

Чтобы заставить подключение веб-сокетов работать, выполняется большой объем работы за кулисами. Прежде всего, веб-страница устанавливает связь по обычному стандарту HTTP. Потом это подключение нужно повысить до подключения веб-сокетов, позволяющего свободную двустороннюю связь. На этом этапе возможны проблемы, если между компьютером клиента и веб-сервером находится прокси-сервер (как, например, в типичной корпоративной сети). Прокси-сервер может отказаться сотрудничать и разорвет подключение. Эту проблему можно решить, обнаруживая неудачное подключение (посредством события onError объекта WebSocket) и применяя один из заполнителей (polyfills) для сокетов, описанных на веб-сайте GitHub. Эти заполнители применяют метод опроса, чтобы эмулировать подключение веб-сокетов.

Примеры веб-сокетов в сети

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

Для начала попробуйте сайт websocket.org , который предоставляет простейший сервер веб-сокетов: веб-страница отправляет ему сообщение, а он возвращает это же сообщение веб-странице:

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

Var socket = new WebSocket("ws://echo.websocket.org"); socket.onopen = connectionOpen; socket.onmessage = messageReceived; function connectionOpen() { socket.send("UserName:[email protected]"); } function messageReceived(e) { var messageLog = document.getElementById("messageLog"); messageLog.innerHTML += "
" + "Ответ сервера: " + e.data; }

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

Your browser may not support the functionality in this article.

Проблема: время реакции при обмене данными между сервером и клиентом

Интернет создавался главным образом на основе так называемой парадигмы запросов и ответов, реализованной с помощью протокола HTTP. Она заключается в том, что пока клиент не отправит запрос на открытие следующей страницы, она не загрузится. Примерно с 2005 г. с появлением технологии AJAX работа в Интернете стала более динамичной. При этом обмен данными по протоколу HTTP все равно инициировался клиентом, и это требовало от пользователя выполнения определенных действий или периодического опроса сервера для загрузки обновленной информации.

Технологии, позволяющие серверу отправлять клиенту новые данные в момент их появления, существуют довольно давно. Они известны как Push или Comet . Один из распространенных способов создания иллюзии соединения, инициируемого сервером, – это так называемый метод длинного опроса. Его суть в том, что клиент создает подключение к HTTP-серверу и оно не закрывается до отправки ответа. Если на сервере действительно есть обновленные данные, он отправляет ответ (в других технологиях для этого используются Flash , multipart-запросы XHR и особые HTML-файлы). Технология длинного опроса, как и другие подобные приемы, прекрасно работает. Вы пользуетесь ими каждый день, например, в чате Gmail.

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

Знакомство с протоколом WebSocket: использование веб-сокетов в Интернете

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

Начало работы

Чтобы создать подключение WebSocket, можно вызвать соответствующий конструктор.

Var connection = new WebSocket("ws://html5rocks.websocket.org/echo", ["soap", "xmpp"]);

Обратите внимание на ws: : это новая схема URL для веб-сокетов. Для создания безопасных веб-сокетов также используется схема wss: , аналогично протоколу https: для безопасных HTTP-соединений.

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

Второй аргумент позволяет использовать дополнительные субпротоколы. Это может быть строка или массив строк. Каждая из них должна соответствовать названию субпротокола, а сервер принимает только один из переданных с помощью массива параметров. Список поддерживаемых субпротоколов приведен в свойстве protocol объекта WebSocket.

Названия субпротоколов должны соответствовать реестру IANA . По состоянию на февраль 2012 г. зарегистрировано только одно такое название (soap).

// When the connection is open, send some data to the server connection.onopen = function () { connection.send("Ping"); // Send the message "Ping" to the server }; // Log errors connection.onerror = function (error) { console.log("WebSocket Error " + error); }; // Log messages from the server connection.onmessage = function (e) { console.log("Server: " + e.data); };

Обмен данными с сервером

После установки соединения с сервером (срабатывания события open) ему можно отправлять данные с помощью метода send("сообщение") объекта подключения. Ранее она принимала только строки, однако в последней версии спецификации поддерживаются и двоичные сообщения. Для отправки таких данных используются объекты Blob и ArrayBuffer .

// Sending String connection.send("your message"); // Sending canvas ImageData as ArrayBuffer var img = canvas_context.getImageData(0, 0, 400, 320); var binary = new Uint8Array(img.data.length); for (var i = 0; i

Сервер также может в любой момент отправить нам сообщение. Когда это происходит, срабатывает обратный вызов onmessage . Этот вызов получает объект события, а поступившее сообщение можно увидеть в свойстве data .

Согласно последней версии спецификации, объект WebSocket также способен принимать двоичные сообщения. Двоичные фреймы можно получать в форматах Blob или ArrayBuffer . Чтобы указать формат полученного двоичного фрейма, необходимо задать для свойства binaryType объекта WebSocket значение blob или arraybuffer. Форматом по умолчанию является blob. (Проверять параметр binaryType при отправке не требуется.)

// Setting binaryType to accept received binary as either "blob" or "arraybuffer" connection.binaryType = "arraybuffer"; connection.onmessage = function(e) { console.log(e.data.byteLength); // ArrayBuffer object if binary };

Еще одной новой функцией WebSocket являются расширения. С их помощью можно отправлять сжатые , мультиплексированные фреймы и т. п. Список поддерживаемых сервером расширений приведен в свойстве extensions объекта WebSocket после срабатывания события open. По состоянию на февраль 2012 г. официальных спецификаций для расширений нет.

// Determining accepted extensions console.log(connection.extensions);

Обмен данными между разными доменами

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

Прокси-серверы

В любой новой технологии есть свои подводные камни. Для протокола WebSocket проблемой является совместимость с прокси-серверами – посредниками в HTTP-соединениях в большинстве корпоративных сетей. Протокол WebSocket использует систему модернизации HTTP (она обычно применяется для HTTP/SSL) для "модернизации" HTTP-соединения по данному протоколу. Некоторые прокси-серверы не поддерживают ее, и происходит сбой подключения. Таким образом, даже если клиент использует протокол WebSocket, установить соединение будет невозможно. Поэтому следующий раздел крайне важен.

Преимущества веб-сокетов уже сегодня

Технология WebSocket появилась совсем недавно и не полностью реализована во всех браузерах. Несмотря на это, можно воспользоваться упомянутыми выше библиотеками для реализации в случаях, когда протокол WebSocket не поддерживается. Одной из самых популярных библиотек является socket.io , в которой возможности протокола реализованы как на стороне сервера, так и на стороне клиента, а также обеспечена обратная совместимость (по состоянию на февраль 2012 г. socket.io не поддерживает обмен двоичными сообщениями). Существуют и коммерческие решения, например PusherApp , который легко интегрируется в любые веб-приложения и реализуют отправку сообщений WebSocket клиентам с помощью API на базе HTTP. Использование HTTP-запросов неизменно повышает потребление ресурсов в сравнении со стандартной технологией WebSocket.

На стороне сервера

Использование протокола WebSocket меняет подход к применению серверных приложений. Хотя традиционные наборы серверного программного обеспечения, например LAMP, разработаны для обычного цикла запросов и ответов на базе HTTP, они часто плохо работают в условиях большого числа WebSocket-подключений. Большое количество одновременных соединений требует принципиально новой архитектуры, которая сочетает низкую ресурсоемкость с возможностями параллельной работы. Такие архитектуры обычно создаются на основе потоковой или так называемой неблокирующей системы обмена данными.

Пару недель назад разработчики Google Chromium опубликовали новость о поддержке технологии WebSocket. В айтишном буржунете новость произвела эффект разорвавшейся бомбы. В тот же день различные очень известные айтишники опробовали новинку и оставили восторженные отзывы в своих блогах. Моментально разработчики самых разных серверов/библиотек/фреймворков (в их числе Apache, EventMachine, Twisted, MochiWeb и т.д.) объявили о том, что поддержка ВебСокетов будет реализована в их продуктах в ближайшее время.
Что же такого интересного сулит нам технология? На мой взгляд, WebSocket - это самое кардинальное расширение протокола HTTP с его появления. Это не финтифлюшки, это сдвиг парадигмы HTTP . Изначально синхронный протокол, построенный по модели «запрос - ответ», становится полностью асинхронным и симметричным . Теперь уже нет клиента и сервера с фиксированными ролями, а есть два равноправных участника обмена данными. Каждый работает сам по себе, и когда надо отправляет данные другому. Отправил - и пошел дальше, ничего ждать не надо. Вторая сторона ответит, когда захочет - может не сразу, а может и вообще не ответит. Протокол дает полную свободу в обмене данными, вам решать как это использовать.

Я считаю, что веб сокеты придутся ко двору, если вы разрабатываете:
- веб-приложения с интенсивным обменом данными, требовательные к скорости обмена и каналу;
- приложения, следующие стандартам;
- «долгоиграющие» веб-приложения;
- комплексные приложения со множеством различных асинхронных блоков на странице;
- кросс-доменные приложения.

И как это работает?

Очень просто! Как только ваша страница решила, что она хочет открыть веб сокет на сервер, она создает специальный javascript-объект:

  • < script >
  • ws = new WebSocket("ws://site.com/demo" );
  • // и навешивает на новый объект три колл-бека:
  • // первый вызовется, когда соединение будет установлено:
  • ws.onopen = function () { alert("Connection opened..." ) };
  • // второй - когда соединено закроется
  • ws.onclose = function () { alert("Connection closed..." ) };
  • // и, наконец, третий - каждый раз, когда браузер получает какие-то данные через веб-сокет
  • ws.onmessage = function (evt) { $("#msg" ).append("

    " +evt.data+"

    " ); };
  • * This source code was highlighted with Source Code Highlighter . А что при этом происходит в сети? Все начинается так же как в обычном HTTP-запросе. Браузер подключается по протоколу TCP на 80 порт сервера и дает немного необычный GET-запрос:
    GET /demo HTTP/1.1
    Upgrade: WebSocket
    Connection: Upgrade
    Host: site.com
    Origin: http://site.com

    Если сервер поддерживает ВебСокеты, то он отвечает таким образом:
    HTTP/1.1 101 Web Socket Protocol Handshake
    Upgrade: WebSocket
    Connection: Upgrade
    WebSocket-Origin: http://site.com
    WebSocket-Location: ws://site.com/demo

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

    0x00, , 0xFF
    То есть просто строка текста - последовательность байт, к которой спереди приставлен нулевой байт 0x00, а в конце - 0xFF. И все - никаких заголовков, метаданных! Что именно отправлять, разработчики полностью оставили на ваше усмотрение: хотите XML, хотите JSON, да хоть стихи Пушкина.
    Каждый раз, когда браузер будет получать такое сообщение, он будет «дергать» ваш колл-бек onmessage.

    Легко понять, что КПД такого протокола стремится к 95%. Это не классический AJAX-запрос, где на каждую фитюльку приходится пересылать несколько килобайт заголовков. Разница будет особенно заметна если делать частый обмен небольшими блоками данных. Скорость обработки так же стремится к скорости чистого TCP-сокета - ведь все уже готово - соединение открыто - всего лишь байты переслать.

    Лирическое отступление:
    И еще одна вещь, которая меня очень радует - в качестве единственной разрешенной кодировки выбрана UTF-8! Я уже робко надеюсь, что через некоторое время мы уйдем от одного из костылей веба.
    А картинку можно отправить? С помощью WebSockets так же можно передавать и бинарные данные. Для них используется другой дата-фрейм следующего вида:
    0x80, ,
    Что значит «один или несколько байт»? Чтобы не создавать ограничений на длину передаваемого сообщения и в тоже время не расходовать байты нерационально, разработчики использовали очень хитрый способ указания длины тела сообщения. Каждый байт в указании длины рассматривается по частям: самый старший бит указывает является ли этот байт последним (0) либо же за ним есть другие (1), а младшие 7 битов содержат собственно данные. Обрабатывать можно так: как только вы получили признак бинарного дата-фрейма 0x80, вы берете следующий байт и откладываете его в отдельную «копилку», смотрите на следующий байт - если у него установлен старший бит, то переносите и его в «копилку», и так далее, пока вам не встретится байт с 0 старшим битом. Значит это последний байт в указателе длины - его тоже переносите в «копилку». Теперь из всех байтов в «копилке» убираете старшие биты и слепляете остаток. Вот это и будет длина тела сообщения. Еще можно интерпретировать как 7-битные числа без старшего бита.

    Например, самую главную картинку веб-дизайна - прозначный однопиксельный GIF размером 43 байта можно передать так:

    0x80, 0x2B,
    Объект размером 160 байт закодируется 2 байтами длины:
    0x80, 0x81, 0x20,
    Не правда ли, очень элегантно?Что это нам дает? Скорость и эффективность Высокую скорость и эффективность передачи обеспечивает малый размер передаваемых данных, который иногда даже будет помещаться в один TCP-пакет - здесь, конечно, же все зависит от вашей бизнес-логики. (В дата-фрейм можно засунуть и БСЭ, но для такой передачи потребуется чуть больше 1 TCP- пакета. :)).
    Так же учтите, что соединение уже готово - не надо тратить время и трафик на его установление, хендшейки, переговоры.Стандартность Самим своим выходом WebSockets отправит на свалку истории Comet и все приблуды накрученные поверх него - Bayuex, LongPolling, MultiPart и так далее. Это все полезные технологии, но по большей части, они работают на хаках, а не стандартах. Отсюда периодески возникают проблемы: то прокся ответ «зажевала» и отдала его только накопив несколько ответов. Для «пробивания» проксей часто использовался двух-килобайтный «вантуз» - т.е. объем передаваемых данных увеличивался пробелами (или другими незначащими символами) до 2К, которые многие прокси передавали сразу, не задерживая. Периодически антивирусы выражали свое желание получить ответ полностью, проверить его, и только потом передать получателю. Конечно, сегодня все эти проблемы более-менее решены - иначе бы не было такого большого кол-ва веб-приложений. Однако, развитие в этом направлении сопряжено с появлением новых проблем - именно потому, что это попытка делать в обход стандарта.

    На мой взгляд, через некоторое время останется только 2 технологии: чистый AJAX и WebSockets. Первая хороша для одно- или несколькоразовых обновлений на странице - действительно, врядли рационально для этого раскочегаривать мощную машину веб-сокетов. А все остальное, что сейчас делается кометом и коллегами, переедет на веб-сокеты, т.к. это будет проще и эффективнее. Например, вы хотите вживую мониторить цены на рынке форекс . Пожалуйста: открывайте сокет - сервер вам будет присылать все обновления. Ваша задача только повесить правильный колл-бек на событие onmessage и менять циферки на экране. Вы решили что-то прикупить, отправьте серверу асинхронное сообщение, а параллельно продолжайте получать циферки. Элегантно? По сравнению с этим LongPolling с необходимостью периодческого рестарта даже неактивного канала (чтобы его прокся или еще кто не прихлопнул) выглядит грязным хаком.

    Время жизни канала В отличие от HTTP веб-сокеты не имеют ограничений на время жизни в неактивном состоянии. Это значит, что больше не надо периодически рефрешить соединение, т.к. его не вправе «прихлопывать» всякие прокси. Значит, соединение может висеть в неактивном виде и не требовать ресурсов. Конечно, можно возразить, что на сервере будут забиваться TCP-сокеты. Для этого достаточно использовать хороший мультиплексор, и нормальный сервер легко потянет до миллиона открытых коннектов.Комплексные веб-приложения Как известно в HTTP предусмотрено ограничение на число одновременных октрытых сессий к одному серверу. Из-за этого если у вас много различных асинхронных блоков на странице, то вам приходилось делать не только серверный, но и клиентский мультиплексор - именно отсюда идет Bayeux Protocol .
    К счастью, это ограничение не распространяется на веб-сокеты. Открываете столько, сколько вам нужно. А сколько использовать - одно (и через него все мультиплексировать) или же наоборот - на каждый блок свое соединение - решать вам. Исходите из удобства разработки, нагрузки на сервер и клиент.Кросс-доменные приложения И еще один «камень в ботинке» AJAX-разработчика - проблемы с кросс-доменными приложениями. Да, и для них тоже придумана масса хаков. Помашем им ручкой и смахнем скупую слезу. WebSockets не имеет таких ограничений. Ограничения вводятся не по принципу «из-того-же-источника», а из «разрешенного-источника», и определяются не на клиенте, а на сервере. Думаю, внимательные уже заметили новый заголовок Origin. Через него передается информация откуда хотят подключиться к вашему websocket-у. Если этот адрес вас не устраивает, то вы отказываете в соединение.
    Все! Конец кросс-доменной зопяной боли!А руками пощупать можно? Можно!

    UPDATE: Одной из открытых реализаций веб-сокетов является чат на www.mibbit.com (заметка в их блоге).
    PHP-реализация сервера WebSocket также представлена модулем к асинхронному фреймворку

    (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 мс) проверяет наличие новых сообщений на сервере.



    Есть вопросы?

    Сообщить об опечатке

    Текст, который будет отправлен нашим редакторам: