sonyps4.ru

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

Что такое 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 повсеместно. Или getting started with WebSocket PHP без phpDaemon

    Здравствуйте! Простите за столь длинный заголовок, но, надеюсь, что новичкам вроде меня будет легче найти эту статью, ведь мне ничего подобного найти не удалось. Несколько недель назад я принял решение переработать игровой клиент и сервер своей игры Growing Crystals с AJAX, на WebSocket, но всё оказалось не просто непросто, а очень сложно. Поэтому я и решил написать статью, которая бы помогла самым что ни на есть начинающим разработчикам на WebSocket + PHP сэкономить несколько дней времени, максимально подробно объясняя каждый свой шаг по настройке и запуску первого WebSocket скрипта на PHP.

    Код сокет-сервера на PHP я приводить не буду, т.к. он есть в архиве и снабжен комментариями. Я искусственно ограничил время работы приёмки соединений 100 секундами, чтобы скрипт он не оставался в памяти, закрывал все соединения и не приходилось при внесении в него изменений постоянно перезагружать Денвер. При чем, по прошествии 100 секунд, скрипт не прекратит свою работу, а будет ждать подключения, после которого его работа будет завершена, а все сокеты благополучно закрыты. Также, для тестирования, я использую localhost и порт 889.

    Socket_bind($socket, "127.0.0.1", 889);//привязываем его к указанным ip и порту

    Файлы из архива можно поместить в корневую папку localhost Денвера. Алгоритм тестирования:

  • Запускаем http://localhost/socket.html , он автоматически подключится к ws echo серверу ws://echo.websocket.org, можно отправить несколько сообщений, которые сервер должен отправить обратно, ведь это же эхо-сервер. Если это работает - отлично, с клиентом всё в порядке, если нет, проверьте все ли вы файлы разместили в одном каталоге, запущен ли у вас Денвер, и есть ли соединение с сетью Интернет.
  • Откройте в этой же вкладке где у вас открыт ws-клиент JavaScript консоль (В GoogleChrome 34.8.1847.137 m и в FireFox это делается почти одинаково меню->инструменты->консоль Java Script или Ctrl+Shift+J, но лично я использую для этого консоль FireBug). Отправьте еще несколько сообщений. Вы увидите какие сообщения приходят от сервера. Вы можете нажать disconnect и после этого отправить несколько сообщений, вы убедитесь что сообщения не уходят, т.к. связь с сервером ws://echo.websocket.org разорвана.
  • Запускаем в новой вкладке браузера наш сокет-сервер http://localhost/simpleworking.php . Желательно чтобы вы сразу могли видеть и вкладку клиента с консолью и вкладку сервера. Должно появиться GO() ... socket_create ...OK socket_bind ...OK Listening socket... OK

    Что означает, что сервер готов к входящим соединениям.

  • Во вкладке клиента в поле Server address вводим ws://127.0.0.1:889 и нажимаем reconnect, мы видим что на клиенте ничего не происходит, а на сервере появляются сообщения вида Client "Resource id #3" has connected Send to client "Hello, Client!"... OK Waiting... OK

    Что говорит нам о том, что технически соединение с сокетом на сервере установлено, а на клиенте ожидается соединение по протоколу веб-сокет, и оно не установлено, т.к. браузером не получены соответствующие заголовки протокола ws. При попытке отправить сообщение с клиента, в консоли должна появиться ошибка о том, что соедние с ws не установлено. К сожалению, скрипт в GoolgeChrome остановится и для новых попыток подключения придётся перезагружать страницу с веб-клиентом. В FireFox скрипт продолжает выполняться. Обязательно сделайте reconnect спустя 100 секунд, после запуска скрипта сервера, чтобы дать ему благополучно завершиться.

    Client "Resource id #4" has connected Send to client "Hello, Client!"... OK time = 309.8900001049return go() ended Closing connection... OK

  • Чтобы окончательно убедиться в том, что сервер отвечает, что его сообщения не блокируются файрволом, запустите скрипт сервера http://localhost/simpleworking.php запустите telnet и попытайтесь подключиться к 127.0.0.1:889, только это нужно сделать не позднее 100 секунд, с момента запуска сервера, пока он не закрыл соединения и не завершил скрипт.
  • По telnet должен придти ответ «Hello, Client!», что свидетельствует о том, что всё работает в штатном режиме и связь с сервером двухсторонняя.

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

    Протокол веб-сокет

    Теперь остаётся научить наш сокет-сервер общаться как веб-сокет сервер, корректно работать в фоне (демон), и, самое главное, на дешевом хостинге. Немного теории: разрешив серверу выводить на экран сообщение, которое получаем от клиента при попытке подключения, добавив перед строкой $msg = «Hello, Client!»; код

    Echo "Client \"".$accept."\" says:
    ";
    echo socket_read($accept,512);
    echo "";

    можно увидеть, что попытка установить соединение по протоколу веб-сокет всегда сопровождается отправлением клиентом заголовка с обязательным соблюдением формата протокола WebScoket. Тег pre для вывода заголовков выбран не случайно, т.к. в заголовках большое значение играют переносы строк. Такие заголовки я получаю от браузеров, когда пытаюсь подключиться к нашему ws://127.0.0.1:889.

    GET / HTTP/1.1 Host: localhost:889 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Sec-WebSocket-Version: 13 Origin: http://localhost Sec-WebSocket-Key: ndHtpnSPk2H0qOeP6ry46A== Cookie: vc=3; __gads=ID=9eabc58c385071c7:T=1400699204:S=ALNI_Ma_g9PZBXpi_MLKDBsao3LQiGx-EA Connection: keep-alive, Upgrade Pragma:

    GET / HTTP/1.1 Upgrade: websocket Connection: Upgrade Host: localhost:889 Origin: http://localhost Pragma: no-cache Cache-Control: no-cache Sec-WebSocket-Key: zNMTfmc+C9UK6Ztmv4cE5g== Sec-WebSocket-Version: 13 Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36

    Еще до того, как я начал изучать веб-сокеты, мне казалось, что работа с веб-сокетами будет напоминать работу с AJAX, когда мы отправляли запросы серверу используя JavaScript XMLHttpRequest(), но в реальности задача оказалась намного сложнее, и в первую очередь потому, что WebSocket это протокол находящийся на одном уровне с протоколом HTTP (но с некоторыми нюансами) в сетевой модели OSI , что означает, нам на стороне сервера, нужно реализовывать функционал похожий на обработку HTTP (который всегда выполнял Apache). Продолжая сравнения с AJAX, в AJAX нам не нужно обеспечивать работу протокола HTTP, т.к. это всё делает браузер и веб-сервер Apache. Мы просто отправляем и получаем сообщения. Но, использование ws хоть и накладывает на нас достаточно большой объём работы связанный с реализацией сервера на PHP, оно также даёт и преимущества: сокращение объёма передаваемых данных и рост производительности серверного ПО. Для успешного общения с клиентами по протоколу WebSocket сервер должен строго выполнять требования стандарта RFC6455 , подробно описывающего форматы заголовков ответов. Все сообщения отправляемые по протоколу WebSocket можно разделить на несколько видов: handsnake (рукопожатие при установлении связи), ping-pong(проверка связи) и data-transfer(передача данных). Также есть более краткое описание протокола в общих чертах на русском . Для того, чтобы обеспечить полноценное корректное общение сервера и клиента по протоколу веб-сокет, необходима реализация функций на PHP получения и разбора заголовков от клиента, составление заголовков сервером, составление ключа и ряд других. Изучив материалы представленные на хабре и других ресурсах, удалось найти реализованные годные функции , единственным смущающим различием явлилось то, что большинство авторов используют потоковые функции работы с сокетами , они считаются более компактными, но, при этом, более ресурсоёмкими в связи с использованием буфера. Для перехода на потоковые функции работы с сокетами, не требуется установка никаких дополнительных модулей кроме уже установленных, т.к. потоки встроены в PHP 5 по умолчанию. Потоковые функции работы с сокетами всегда начинаются с stream_socket_*. При использовании потоковых функций, желательно убедиться в phpinfo() в поддержке необходимого транспорта для потоков.

    Registered Stream Socket Transports: tcp, udp.

    В случае если такой информации в phpinfo() нет или в случае возникновения других проблем, обратитесь к документации , но проблема решается банальным обновлением Денвера на актуальную версию.
    Еще важным является тот факт, что большинство систем ограничивает возможность создания сокета на порту ниже чем 1024, поэтому во всех дальнейших программах для сокета будет использоваться порт 8889.
    Взяв за основу исходные коды функций кодирования и декодирования заголовков протокола WebSocket, удалось реализовать полноценный ws echo сервер. Алгоритм его работы также прост как и в предыдущем случае: создаём ws сервер используя функцию stream_socket_server, запускаем бесконечный цикл в котором проверяем наличие новых соединений и при получении нового соединения размещаем его в массиве $connects, также запускаем второй цикл, который пробегает по всем соединениям и закрывает отвалившиеся и получает сообщения от открытых соединений. Также в скрипт PHP мною добавлено три функции, которые я оформил как обработчиков событий.

    Function onOpen($connect, $info) {
    echo "open OK
    \n";
    }

    function onClose($connect) {
    echo "close OK
    \n";
    }

    function onMessage($connect, $data) {
    $f = decode($data);
    echo "Message:";
    echo $f["payload"] . "
    \n";
    fwrite($connect, encode($f["payload"]));
    }

    Которые ничего не делают, за исключением вывода сообщений о событиях на экран. И при получении сообщения от клиента, раскодируем его и отправляем его текст, предварительно закодировав, обратно. , ws клиент не изменился. Можно протестировать ws echo server скачав архив, и разместив его в корневой папке localhost-а Денвера. Подключиться клиентом к адресу ws://127.0.0.1:8889.
    Тонкости связанные с запуском ws сервера в фоне (демон), и запуск на хостинге мы разберем в . Буду рад комментариям и отзывам.

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

    Мои статьи про PHP демонов и веб-сокеты
    • Простой веб-сокет на PHP или веб сокеты с абсолютного 0

    22.9. Веб-сокеты

    В главе 18 демонстрируется, как клиентские сценарии на языке JavaScript могут взаимодействовать с серверами по сети. Все примеры в этой главе используют протокол HTTP, а это означает, что все они ограничены исходной природой протокола HTTP: этот протокол, не имеющий информации о состоянии, состоит из запросов клиента и ответов сервера. Протокол HTTP фактически является узкоспециализированным сетевым протоколом. Более универсальные сетевые взаимодействия через Интернет (или через локальные сети) часто реализуются с использованием долгоживущих соединений и обеспечивают двунаправленный обмен сообщениями через TCP-сокеты. Довольно небезопасно предоставлять клиентскому сценарию на языке JavaScript доступ к низкоуровневым ТСР-сокетам, однако спецификация «WebSocket АРІ» определяет безопасную альтернативу: она позволяет клиентским сценариям создавать двунаправленные соединения с серверами, поддерживающими протокол веб-сокетов. Это существенно упрощает решение некоторых сетевых задач.

    Прикладной интерфейс веб-сокетов удивительно прост в использовании. Сначала необходимо создать сокет с помощью конструктора WebSocket():
    var socket = new WebSocket("ws://ws.example.com:1234/resource");

    Протокол веб-сокетов

    Чтобы использовать веб-сокеты в сценариях на языке JavaScript, достаточно будет освоить клиентский прикладной интерфейс веб-сокетов, описываемый здесь. Не существует эквивалентного серверного прикладного интерфейса для создания серверов с поддержкой веб-сокетов; в этом разделе будет представлен простой пример сервера, основанного на использовании интерпретатора Node (раздел 12.2) и сторонней серверной библиотеки поддержки веб-сокетов. Клиент и сервер взаимодействуют через долгоживущие TCP-сокеты, следуя правилам, определяемым протоколом веб-соке-тов. Мы не будем рассматривать здесь особенности протокола, но следует отметить, что протокол веб-сокетов спроектирован очень аккуратно, благодаря чему веб-серверы могут легко обрабатывать HTTP-соединения и соединения на основе веб-сокетов через один и тот же порт.

    Веб-сокеты получили широкую поддержку среди производителей броузеров. В ранней, предварительной версии протокола веб-сокетов была обнаружена серьезная брешь в системе безопасности, поэтому на момент написания этих строк в некоторых броузерах поддержка веб-сокетов была отключена, - до стандартизации безопасной версии протокола. В Firefox 4, например, может потребоваться явно включить поддержку веб-сокетов, открыв страницу about:config и установив переменную «network.websocket. override-security-block» в значение true.

    *********************************************

    Аргументом конструктора WebSocket() является URL-адрес, в котором используется протокол ws:// (или wss:// - в случае с безопасными соединениями, по аналогии с https://). URL-адрес определяет имя хоста, к которому выполняется подключение, и может также определять порт (по умолчанию веб-сокеты используют тот же порт, что и протоколы HTTP и HTTPS) и путь или ресурс.

    После создания сокета в нем обычно регистрируются обработчики событий:

    socket.onopen = function(e) { /* Соединение установлено. */ };
    socket.onclose = function(e) { /* Соединение закрыто. */ };
    socket.onerror = function(e) { /* Что-то пошло не так! */ };
    socket.onmessage = function(e) {
    var message = e.data; /* Сервер послал сообщение. */
    };

    Чтобы отправить данные серверу через сокет, следует вызвать метод send() сокета:

    socket.send("Привет, сервер!");

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

    По окончании взаимодействия с сервером сценарий может закрыть веб-сокет вызовом его метода close() .

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

    В разделе 18.3 описывается прикладной интерфейс объекта EventSource и демонстрируется его применение на примере реализации клиента и сервера чата. Вебсокеты еще больше упрощают реализацию подобных приложений. В примере 22.16 демонстрируется очень простой клиент чата: он напоминает пример 18.15, но использует веб-сокеты для двунаправленного обмена сообщениями вместо объекта EventSource для приема сообщений и XMLHttpRequest - для отправки.

    Пример 22.16. Клиент чата на основе веб-сокетов


    window.onload = function() {
    // Позаботиться о некоторых деталях пользовательского интерфейса
    var nick = prompt("Введите свой псевдоним"); // Получить псевдоним
    var input = document.getElementById("input"); // Отыскать поле ввода
    input.focus(); // Установить фокус ввода
    // Открыть веб-сокет для отправки и приема сообщений в чате.
    // Предполагается, что HTTP-сервер, откуда загружается сценарий, также
    // поддерживает веб-сокеты, и для связи с ним используется то же имя хоста
    // и номер порта, но вместо протокола http:// используется протокол ws://
    var socket = new WebSocket("ws://" + location.host + "/");
    // Так через веб-сокет принимаются сообщения с сервера
    socket.onmessage = function(event) { // Вызывается при получении сообщения
    var msg = event.data; // Получить текст из объекта события
    var node = document.createTextNode(msg); // Создать текстовый узел
    var div = document.createElement("div"); // Создать элемент
    div.appendChild(node); // Добавить текстовый узел
    document.body.insertBefore(div, input); // и вставить div перед полем ввода
    input.scrollIntoView(); // Гарантировать видимость элемента input
    }
    // Так через веб-сокет отправляются сообщения на сервер
    input.onchange = function() { // Когда пользователь нажмет клавишу Enter
    var msg = nick + ": " + input.value; // Имя пользователя и текст
    socket.send(msg); // Отправить через сокет
    input.value = ""; // Подготовиться к вводу следующего сообщения
    }
    };





    Загрузка...