Оглавление Предыдущая лекция Следующая лекция
Введение в HTML5
7. Лекция: Введение в сокеты Web: версия для печати и PDA
Приводится описание API сокетов HTML5 с примерами использования. Основные протоколы для обмена информацией между клиентскими и серверными приложениями. Методы, свойства и события объекта WebSocket. Описаны конструкторы для создания соединения с сервером, использующие различные настройки. Открытие и закрытие соединений. Характеристика сообщений от сервера, обработка основных ошибок, возникающих при работе с сокетами. Методики проверки поддержки сокетов в браузере клиента.
Брюс Лоусон, Майк Тейлор · 22 ноября 2010 г.

Сокеты Web отключены по умолчанию в связи со спецификацией связанной с проблемами безопасности. Тем не менее, можно включить их в браузере Opera с помощью opera:config#UserPrefs|EnableWebSockets.

Введение

Бета-версия Opera 11 продемонстрировала поддержку сокетов Web, свойства, которое было ранее частью спецификации HTML5, известное как TCPConnection (http://www.w3.org/TR/2008/WD-html5-20080610/comms.html#tcpconnection). Однако сегодня сокеты Web определяются в двух местах: Web Sockets API (http://www.w3.org/TR/websockets/) поддерживает редактор HTML5 Ян Хиксон, в то время как протокол (http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol) редактирует Ян Фетте. Сокеты Web позволяют приложению передавать информацию между сервером и браузером, а не опрашивать сервер с заданным интервалом времени или использовать нестандартные приемы с помощью <iframe> — это позволяет разработчикам web уменьшить ненужный трафик HTTP и сложность программирования.

В этой статье мы объясняем предпосылки создания сокетов Web, показываем, почему это полезное свойство, и демонстрируем несколько примеров простого использования.

История сокетов Web

Существует городская легенда, что сокеты Web были изобретены Яаном Хиксоном в качестве способа управления моделью поезда из браузера (http://ln.hixie.ch/?start=1113762425). К сожалению, это неправда, так как по словам самого Хиксона (частное сообщение):

Я думаю, что работа над сокетами Web (TCPConnection в то время) предшествовала моим мыслям об управлении моим макетом поезда с помощью сокетов Web, но сокеты Web несомненно могли бы сделать это намного легче. Проблема состоит в том, что обычное приложение Web управляет одиночной системой: имеется один компьютер, соединенный через последовательный порт с устройством Marklin Interface (https://secure.wikimedia.org/wikipedia/en/wiki/Marklin_Digital), и требуется написать страницу Web, которая взаимодействует с этим компьютером, посылает инструкции и получает обновления, не опрашивая, имеет несколько соединений, использует потоки <script> в <iframe> и т.д.

Почему сокеты Web полезны

API сокетов Web позволяет открывать соединение с сервером, используя новый протокол ws, который остается открытым в течение времени жизни сеанса. Он является полнодуплексным, т.е. допускает коммуникацию в обоих направлениях одновременно. Он также имеет значительно меньшие накладные расходы, чем повторяющиеся обращения к серверу для отслеживания за изменениями. Раньше такие функции были доступны только с помощью технологии плагинов типа Flash.

Тестирование, выполненное компанией Kaazing Corp (http://www.websockets.org/ quantum.html), которая была тесно вовлечена в процесс спецификации, показали, что " Сокеты Web из HTML5 могут обеспечить пятисоткратное — в зависимости от размера заголовков HTTP — и даже тысячекратное сокращение бесполезного трафика заголовков HTTP и трехкратное сокращение времени задержки".

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

Как работают сокеты Web

Сокеты Web включают в себя API JavaScript, описанный ниже, и протокол ws: — или wss: для шифрованной передачи. Браузер Opera поддерживает версию -00 протокола (обозначаемую также -76). То же самое относится к Chrome 6, Safari 5.0.2 и Firefox 4 beta. Протокол стандартизован в IETF (http://www.ietf.org/) и может изменяться; однако изменения API маловероятно. Это означает, что приложение может прекратить работать, если оно общается с сервером, который использует другую версию протокола, но для относительно стабильного клиентского API вам, вероятно, не понадобиться изменять клиентский код.

API сокетов Web

Для соединения с сервером сокета Web, используется конструктор WebSocket следующим образом:

var ws = new WebSocket('ws://example.org:12345/demo');

Можно также запросить специальные субпротоколы с помощью второго параметра:

var ws = new WebSocket('ws://example.org:12345/demo', 'my-chat-protocol');

Если требуется более одного субпротокола, можно передать их в массиве строк (будет поддерживаться в будущей версии браузера Opera):

var ws = new WebSocket('ws://example.org:12345/demo', ['chat-protocol-v2-with-bells-and-whistles', 'chat-protocol']);

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

Можно пытаться соединиться с любым хостом и любым портом, за исключением блокированных портов, однако сервер должен поддерживать сокеты Web и будет ожидать соединение от определенной страницы, которая, как ожидается, открывает соединение. Субпротокол, если используется, является произвольной строкой (состоящей из печатных символов ASCII), которая гарантирует, что клиент и сервер посылают сообщения, которые являются взаимно понятными. Например, Caucho Technology (http://blog.caucho.com/?p=500) пишет, что субпротоколы полезны "чтобы гарантировать, что клиент Quake/2.0 [WebSocket] не будет путаться, общаясь с сервером Quake/1.0 [WebSocket]".

Если соединение установлено, объект WebSocket получает событие open, и после этого можно начинать отправлять и получать сообщения. В контексте сокетов Web, сообщение является просто строкой текста, например, в формате JSON. Вы посылаете сообщение с помощью метода send(), и обрабатываете входящие сообщения с помощью перехватчика событий onmessage:

ws.onopen = function(e) {
// соединение теперь установлено 
// давайте пошлем простое сообщение 
this.send('{"username": "Bruce", "message": "Hello!"}');
}
ws.onmessage = function(e) {
// получить сообщение с сервера 
var msg = JSON.parse(e.data);
alert(msg.message);
}

Если сервер отказывает в соединении, или если соединение закрывается по какой-то причине, объект WebSocket получает сообщение close.

ws.onclose = function(e) {
alert('WebSocket closed :-(');
}

Соединение можно закрыть с помощью метода close():

ws.close();

Если сервер посылает кадры, которые браузер не понимает (может быть потому что сервер поддерживает только более новую версию протокола), то вы получите событие error. Если вы получаете события error, но не события message, вы можете попробовать закрыть соединение и вернуться к использованию другого средства, например, длинные опросы XHR или сервер Comet.

Функция обнаружения сокетов Web устроена просто — выполните следующее:

if ('WebSocket' in window) {
// Сокеты Web поддерживаются 
} else {
// Сокеты Web не поддерживаются 
}

Или если вы уже используете Modernizr (http://www.modernizr.com/) в своем приложение, то обнаружение будет таким же простым:

if (Modernizr.websockets) {
// Сокеты Web поддерживаются 
} else {
// Сокеты Web не поддерживаются 
}

Как быть в случае неподдерживающих сокеты Web браузеров?

Вики HTML5 Cross browser Polyfills (https://github.com/Modernizr/Modernizr/ wiki/HTML5-Cross-browser-Polyfills) перечисляет три сценария, которые можно использовать в качестве средства симуляции сокетов Web для более старых, неподдерживающих сокеты Web браузеров (отметим, что мы не проверяли все такие браузеры). Проект Socket.IO (http://socket.io/) является особенно хорошим решением, так как он соединяет сервер сокета Web Node.js с унифицированным, абстрактным API с автоматическим откатом к сокетам Flash, длинному опросу AJAX, многокомпонентному потоковому AJAX, потоковому <iframe> и JSONP для более слабых клиентов. Socket.IO распространяется с открытым исходным кодом и работает с Node.js (http://nodejs.org/), с несколькими другими совместимыми реализациями для других серверных технологий.

Демонстрация

Следующие приложения используют сокеты Web для предоставления многопользовательского взаимодействия (почти) в реальном времени:

  • Mr. Doob's Multiuser Sketchpad (http://mrdoob.com/projects/multiuserpad/): В этом многопользовательском приложении рисования с помощью <canvas>, сокеты Web используются для передачи координат линий, которые другие пользователи рисуют на каждом клиенте как получится.
  • Rumpetroll (http://rumpetroll.com/): В качестве головастика вы можете плавать и общаться с другими головастиками. Сокеты Web предназначены для определения местонахождения головастиков и сообщений, которые передаются каждому пользователю.
  • wordsquared.com (http://wordsquared.com/): В этой многопользовательской сетевой игре со словами сокеты Web используются, чтобы пользователи видели карточки других игроков во время игры.

Кроме этих демонстраций Ericsson Labs имеет интересный видеофильм, демонстрирующий преимущества сокетов Web по сравнению с длинными опросами HTTP для приложений реального времени:

Ресурсы

© INTUIT.ru