
Пару недель назад разработчики 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("<p>"+evt.data+"</p>"); };
-
- </script>
* 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, <строка в кодировке UTF-8>, 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 также представлена модулем к асинхронному фреймворку
phpDaemon, модуль называется
WebSocketServer. Пример простейшего приложения, которое отвечает «pong» на фрейм (пакет) «ping» —
ExampleWebSocket.
Вы можете попутно прослушать соедиение с помощью например tcpdump или любой другой программы и увидеть в действии всю ту механику, которую я описал выше.
Светлое будущее
И когда же оно настанет? На самом деле очень скоро. Гугл в очередной раз дал «волшебного пендаля» всей веб-индустрии, и все зашевелились. Вы удивитесь, но тут же люди вспомнили, что в багзилле фаерфокса уже год(!)
висит задача на эту тему. В Хроме все изменения сделаны в WebKit — а значит очень скоро появится поддержка в Safari. Скоро подтянутся и остальные браузеры.
А если нельзя, но очень хочется?
На этот случай придуман временный заменитель — библиотечка
web-socket-js с помощью флеша эмулирующая веб-сокеты. К сожалению, у нее есть небольшие проблемы с проксями и кросс-доменной работой. Но в качестве временного решения ее стоит опробовать.
Выводы
На мой взгляд, как только люди распробуют, эта технология получить очень широкое распространение. К весне-лету мы получим массу сайтов с ней. И как в свое время несколько лет прошло «под звездой AJAX», так и здесь год-другой мы будем слышать отзывы о внедрении WebSockets повсеместно.
...
Осторожно, двери закрываются. Не опоздайте на поезд в будущее...
Оригинал:
Введение в WebSockets — полноценный асинхронный веб
комментарии (357)
Только на днях начал ковырять comet-технологию, а тут такое.
Будем-с ждать :)
Насколько активно мы итешники будем разрабатывать и пиарить свои сервисы. Чем больше интересных вещей будет, тем быстрее пользователь начнет этим пользоваться.
Например, не совсем ясно, если у комета проблемы с принудительным закрытием злыми проксями долго висящих соединений, то почему таких же проблем не будет у websockets?
Я думаю, что MS поддержит идею, пусть даже не сразу, но ждать долго не заставит.
Если бы не они — пользовался бы IE8.
"… да, знаю, грусть, злоба и осадок на душе остаётся после нескольких лет разработки под IE6.
Но я уже отпустил IE6 и простил его. Пусть отходит с миром. Всё будет хорошо."
Как-то раз на какой-то конференции (не помню, но точно слышал) у дядьки с гугля спросили «а когда же это всё зарботает в IE?» на что он ответил «IE? я не знаю такого браузера» (или как-то так) — вот такая политика.
И БАМ! в IE8 всё работает.
если допустим пользователи gmail не смогут заходить на свою почту (а её часто в последнее время оказывается именно gmail) то от IE они откажутся.
Со времён IE6 политика MS значительно изменилась. Я бы даже сказал, что они существенно поумнели.
Вот этого я жду с содроганием. МС опять окажется в роли догоняющего, а значит реализует в спешке и криво — значит будет брешь в системе. Через нее пойдет большой поток вирусов. Что негативно скажется на мнении о самой технологии, хотя тут она совершенно не виновата. Начнут повсеместно отключать, резать на корпоративных проксях и так далее. Быть может помните, на заре веба была проблема с куков?
В итоге все проиграют: и пользователи, затормозится развитие технологий, и рейтинг самого МС опустится еще ниже плинтуса.
Я думаю таки что-то изменилось, и так
тупитьв МС уже не станут. Тем более, что не так уж будет и сложно сделать поддержку WebSocket без багов, как по мне.Всё будет хорошо ;)
Я думаю, что появление новых сайтов, где удачно будет использована эта технология поможет обновлению браузеров.
Под AJAX вы имели ввиду JSON? :)
Я немного запутал вас в терминологии.
Но возможен такой сценарий: клиент установил подключение до сервера и молчит. Когда серверу потребовались данные — например ФИО пользователя — он сам направляет клиенту асинхронное сообщение. Клиент показывает какую-то форму пользователю, принимает данные и отсылает их на сервер.
В таком варианте вроде бы как сервер спрашивающая сторона. :)
Вот еще важный момент! Поскольку соединение асинхронное то правильнее о нем думать не как о сессии «вопрос-ответ», а как «репликах в воздух».
Веб-сокеты позволят реализовать равноправность «в малом», сохранив разделение «в большом».
К несчастью, я не очень хорошо разбираюсь в особенностях существующих механизма запросов (про аякс, асинхронность и прочее я выводы получил совсем через другие размышления).
Погуглив, нашел статейку на ангельском — вроди в ней есть указания на нужные сведения (и, заодно, о технологии, которой товарисч козырял).
очепяточку поправьте плз. И большое спасибо за интересный материал.
ЗЫ Интересно, если бы такая смелая затея вышла не из гугла, а из чего-то масштабом помельче — прошло бы?
Опять повторился сценарий «волшлебного пендаля», как было с Хромом. Вышел браузер с быстрым яваскриптом и инкогнито-режимом — вроде бы ничего нового — но все тут же подтянулись.
Про чужой комп я не думал…
Всё будет хорошо. Я гарантирую это.
Жаль плюсавать не могу :(
Но впрочем я это за одну только асинхронность готов любить. Web от client-server становится площадкой общения равноправных игроков — это замечательно
WebSockets по скорости и эффективности передачи данных практически равен чистому TCp-соединению. Здесь не надо слишком сильно оптимизировать, потому мы имеем дело с открытой системой — то есть чтобы все кто угодно могли с ней легко взаимодействовать. Здесь лучше оставить некоторую абстрактность и гибкость.
Protobuf — это чисто гугловая вещь, а WebSockets — общественный стандарт планируемый для широкого использования.
Надо только, чтобы приложение понимало, что оно получает.
WebSockets это фактически TCP over HTTP, так что оверхед есть и немалый.
Не соглашусь с вами. HTTP используется только на начальной стадии, дальше идет почти чистый TCP. Единственное отличие — к передаваемым строкам добавляется по 1 байту в начало и конец.
Неважно чья идея. Главное что google все поддержали в такой супер идее.
Всему своё место. Сокеты будут нужны для динамически изменяющейся информации, например, чаты, новостные ленты и т.п.
В общем надо бы поподробнее почитать.
Подход впринципе правильный т.к. если JAVA и ActiveX шли с десктопа в веб со всеми своими дырками в основном из доступа к локальной фс, javascript идёт наоборот из веба на десктоп и дырки в нём специально делать никто не станет.
гммм, я уже вижу какие вирусы будут этим летом расти )))
короче чем интереснее технология тем важнее в ней верификация сторон учавствующих в обмене.
Вы о каком решении сейчас говорите?
А DOM в браузерах ооочень медленный. Особенно в FF и IE.
DOM, конечно, медленный. Но не думаю, что canvas, управляемый js, будет работать быстрее. С чего бы? DOM все-таки львиную часть работы по отрисовке отдает скомпилированному коду. Canvas — нет.
Мне кажется, что канвас на специфических задачах навороченного и очень динамического GUI вполне может оказаться быстрее. Тем более, что скрипты сейчас чуть ли не в нативный код компилируются.
Вопрос в том, сколь сложные задачи лучше решать с помощью canvas. Реализовывать сложную работу с графикой через всевозможные хитрые манипуляции — глупо. Но и простое отображение текста через canvas — тоже. Где-то в промежутке есть задача, которую одинаково сложно делать как на HTML, так и с cavnas.
dev.opera.com/articles/view/efficient-javascript/?page=3
Не очень понял вас, а как же <input type=«button» ...>?
/>
Покажите мне браузер, который это не поддерживает.
<style type="text/css"> .btn { background: url(img.png) no-repeat; width:16px;height:16px; display:inline-block; } .btn:hover { background: url(imgHover.png); } input.btn { outline: none; border: none; } </style> <input type="button" class="btn" />Спать пора… :)
Вы чертовски правы! Пора спать!
Для верстки текста — согласен HTML рулит.
А для интерфейса типа MS Office, HTML получится сложный и тяжелый
Мне кажется у канваса, в перспективе скорость и легкость (нет dom, стилей и пр....).
Договориться, как отображать HTML гораздо сложнее чем как рисовать на канвасе.
Описание стандарта будет тупо больше, поэтому и сложее. А значит место для разночтений и ошибок.
Сравните стандарт по HTML+CSS и по канвасу.
А строить интерфейсы все равно будут через либы типа ExtJS
Может быть я куда-то не туда посмотрел, но «полностью на canvas рисуется» не увидел.
Зарегистрировался, посмотрел под фаерфоксом — опять же, никакого намёка даже на «только canvas» не обнаружил.
Те же самые кнопочки рисовать может и нарисуешь, а обработчики на них повесить как в рамках canvas'а?
Всему своё место. Старый добрый HTML рано списывать со счетов, он много на что годится.
Как раз постоянное подключение-отключение создаст большую нагрзку.
Вот пример сервера, который поддерживает 1 миллион коннектов, да не просто поддерживает, а работает с ними: www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1
Теперь смогу графики и логи в браузере смотреть в реальном времени.
А вот ws.send('. . .') не показан, например.
Я подумал, что она и так уже длинная — чтобы не мучать читателя часть технологии опустил.
Я думаю Игорь добавит в nginx хороший мультиплексор и это позволит еще снизить нагрузку на сервер по поддержанию множества сокетов.
А когда и на другом конце вместо сервера сможет быть браузер,
так и p2p
livedocs.adobe.com/flash/9.0/ActionscriptLangRefV3/flash/net/NetConnection.html
ps про gnash знаю
и касательно ограничения одновременных соединений — вы уверены, что оно прописано именно в стандарте HTTP? Почему тогда у каждого браузера своё ограничение?
> соединения websocket, раз уж они так сильно похожи на обычные http-запросы?
В споре кривизны с прямизной, однозначно победит кривизна :)
С проксями получается такая ситуация:
— если прокся официальная (прописана в браузере), то она должна поддерживать метод CONNECT — с помощью которого браузер работает по HTTPS — ведь там тоже используется передача бинарных данных.
— если это NAT — то он просто завернет подключение и никто этого не заметит.
— самый сложный случай будет в случае «прозрачной прокси», когда все текущее на 80 порт заворачивается на сквид или другой прокси-сервер — здесь уже как он отработает. Впрочем я не исключаю, что в скором времени они научатся поддерживать веб сокеты.
> и касательно ограничения одновременных соединений — вы уверены, что оно прописано именно в
> стандарте HTTP? Почему тогда у каждого браузера своё ограничение?
Могу путать, но где-то проскавала цифра 2 или 4.
Конечно, это не жесткое ограничение — никто не мешает на своем фаерфоксе поставить цифру побольше. Однако есть некоторое официально рекомендованное значение, чтобы вы ненароком сервер не уронили.
Clients that use persistent connections SHOULD limit the number of
simultaneous connections that they maintain to a given server. A
single-user client SHOULD NOT maintain more than 2 connections with
any server or proxy.
Разумеется, кроме флэша была и другая реализация двустороннего обмена данными.
www.mibbit.com/
> качать на свой компьютер демо-пример вебсокетов на php
А еще есть Jetty, Cometd, Orbited, Lightstreamer
Полный список технологий и серверов есть тут: cometdaily.com/maturity.html
А где оно там используется? Сходу не заметил
> А еще есть…
Вы правы — сейчас появится много серверов с поддержкой WebSockets — некоторые команды уже реализовали ее.
Для использования же WebSockets веб-приложения должны писаться в рассчете на них. Пока эта технология не будет поддерживаться браузерами большинства пользователей — этого не будет. Пока не будет достаточно большого количества таких приложений — производителям других браузеров беспокоиться смысла нет.
Получится ситуация в чем-то аналогичная связанной с IE6: из-за его популярности его все (почти) поддерживают, а то, что в нем работает большинство сайтов поддерживает его популярность.
Если 95% сайтов перестанут поддерживать IE6 — его популярность мгновенно упадет почти до нуля. Если 95% сайтов будут требовать WebSockets — браузеры, его не поддерживающие, очень быстро потеряют пользователей.
Но конкретный сайт, не поддерживающий IE6 из-за этого потеряет посетителей. Конкретный сайт, требующий WebSockets — тоже.
Возможно, некоторым компромиссом будет реализация двух вариантов — с сокетами и без них (или использование того же web-socket-js).
Но:
1. Это сложнее, чем сделать что-то одно.
2. Такая ситуация мало чем угрожает браузерам, не поддерживающим сокеты.
Разве что в браузерах, поддерживающих сокеты, можно будет делать что-то существенно лучшее, чем без них.
Чем ситуация будет принципиально отличаться от, скажем, canvas? Он уже работает во всех основных браузерах, кроме IE. И часто его встретишь где-то кроме демонстрационных страничек?
:-)
Исходя из общеизвестной страсти MS к Google, проигнорирует ли MS данную инициативу?
Если да, то прекрасное так и останется далеко…
С Гугла станется наплевать на поддержку и начать внедрять вебсокеты с graceful fallback до обычных Ajax/Comet. Тут опять же пользователи браузеров с поддержкой WS окажутся в выигрыше.
Но существует протокол WSS — это тот же самый WS только поверх SSL/TLS.
Тоже самое как HTTP / HTTPS.
Чего-то я не видел, например, баннеров, нарисованных
Если бы еще по дефолту все бы жалось в gzip…
Буквально с неделю назад крепко думал, что из-за намеренной неравноправности клиентов и серверов, появившейся черте-когда на тогдашних основаниях и причинах, нынче приходится пользовать какие-то убогие костыли. Рад, что гугл со мной солидарен :D
WebSocket-Origin: site.com
WebSocket-Location: ws://site.com/demo
я немного не понял: может ли злоумышленник, манипулируя этими заголовками получить несанкционированный доступ?
Поэтому, чтобы манипулировать этими заголовками нужно или вмешаться в код браузера, или в поток данных между пользователем и сервером… но если вы можете это сделать, то зачем вам заниматься такой ерундой, как подделка заголовков, если вы и так имеете доступ ко всем данным пользователя?)
Что определит сервер, если клиент окажется злоумышленным и подсунет некорректный Origin?
Особенно если подсунет корректный Origin :-(
Работать это будет только если «разрешенный источник» будет знать про данный конкретный Origin. Иными словами домены по вопросу данного клиента должны между собой перепихнутся. И чем этот перепих лучше тупого проксирования?
Но тут такая картина — из яваскрипта его изменить нельзя, браузер сам пришет что нужно. Если вы взломали браузер — то вы сможете слать что угодно — здесь уже не до проверки Origin-a. То есть такая схема не добавляет новой уязвимости, но дает больше возможностей.
Браузер же обязан не позволять перезагружать компьютер или подключаться с помощью XHTTPRequest к другим доменам?
Да.
И это правильно.
Весь вопрос в том, с чем это сравнивать. Если вы разобьете приложение на 500 тредов, то все равно у вас будет 500 буферов, которые надо прочитать, то есть объем работы это никак не уменьшит. Но наоборот добавится работа по шедулингу (пардон за слово, не подскажете нормальный русский перевод?) всех этих тредов. Плюс возрастут расходы памяти на всевозможные таблицы для хранения служебной информации и т.п. То есть нагрузка серьезно возрастет.
Тредами и даже процессами можно делать, если они сами «дешевые» и легкие. Например, в Erlang VM процессы отъедают меньше 1400 байт для хранения одного процесса в таблице. Такие процессы быстро запускаются и работают, они смогут без проблем держать тысячи соедиений. В более привычных языках есть аналоги green threads в java, taskets в python.
Дали повод глубже задуматься над темой :)
2) comet — более собирательный термин. en.wikipedia.org/wiki/Comet_(programming) даёт 6 вариантов имплементации
WebSockets предполагается как 1 прямой метод, чтобы заменить 6 хаков :)
круто)
Например, открывая YouTube клиент получает JS со списком пиров и ф-цией проверки хеша, пытается соединиться с пирами, качает контент, проверяет хеш. Если соединиться быстро не получается — запрос на видео отправляется самому YouTube.
bitbucket.org/rushman/tx-websockets/src/
my.opera.com/WebApplications/blog/show.dml/438711
event: test-event
data: lorem ipsum
data: lorem ipsum
data: lorem ipsum
это немного более подробное описание, чем у вебсокета
кроме того, вроде бы SSE не позволяет передавать бинарные данные
в общем, на нижнем уровне возможностей у web socket побольше, а про верхний, где вызов обработчиков для события с конкретным именем, он ничего не говорит, но это легко эмулируется
в общем, я рад, что теперь уже два браузера (а скоро три, если сафари подтянется) нативно поддерживают серверные события
в общем, я не понимаю, в чём вы хотите убедить меня сейчас. Моя позиция достаточно полно описана в предыдущем комментарии
Ключевое отличие в том, что SSE — это попытка «легализации» комета с лонг-поллингом — он работает поверх HTTP и имеет все те же проблемы, что его «родители». В частности даже официальная дока говорит о том, что прокси серверы могут закрывать неактивное соединение, поэтому периодически надо отправлять пустые сообщения. SSE — пассивный протокол, браузер «подписывается» на сообщения и дальше просто слушает, что ему пришлют. Самой интересной вещью в нем является контроль потока сообщений, если соединение вдруг разорвалось, то при возобновлении браузер передаст Last-Event-Id и передача начнется с того же места.
WebSockets же кардинально новая вещь — он работает как бы «сбоку» от HTTP на чистом TCP и ему ничего не мешает. Это протокол с 2 активными участниками — оба асинхронно обмениваются сообщениями. Вы можете не только получать сообщения, но и отправлять свои по тому же самому каналу.
С помощью WebSockets можно реализовать функционал SSE, причем работать это будет чуть ли не лучше оригинала. А вот наоборот не получится.
Поэтому, на мой взгляд, SSE уже потерял актуальность. Лично я не хочу тратить на него свое время.
Кстати, если говорить про реализацию в Опере 9, то она не идеальна — в стандарте предусмотрено название тега eventsource, а в опере тег называется event-source
Это недостаток SSE? Но он же есть и в WebSockets. Или WebSockets соединения прокси почему-то не будут закрывать?
Вы как-то очень уж горячо взялись пропагандировать WebSockets и гнать от себя SSE. Вы знаете, что, например, существуют прокси и firewalls, которые режут незнакомые (да и некоторые знакомые, например, Accept-Encoding) заголовки? Как WebSockets будут чувствовать себя с таким софтом. Если мне не изменяет память, это около 10% всех подключений.
Стандарт меняется. Это ещё не релиз.
> заблуждение, это всего лишь расширение протокола.
WebSockets использует HTTP только для коннекта дальше идет чистая TCP-сессия, SSE — на всем протяжении сессии для транспорта.
> Это недостаток SSE? Но он же есть и в WebSockets. Или WebSockets соединения прокси почему-
> то не будут закрывать?
WebSockets через прокси идет как бинарный трафик (метод CONNECT), SSE как чистый HTTP.
> Вы как-то очень уж горячо взялись пропагандировать WebSockets и гнать от себя SSE.
Возможно. SSE оригинальная технология, но это «половинчатое решение», по сути «легализация» уже существующего со всеми их проблемами. WebSockets — кардинальный шаг вперед — я выше описал.
Разработчики уделили пробиваемости проксей немало времени.
> Стандарт меняется. Это ещё не релиз.
Это серьезная проблема. Стандарт еще не готов, а уже устарел. Необходимость в нем уже отпала. Когда он выйдет, WebSockets захватит рынок.
prooflink?
Что они сделали для этого, я не увидел?
Так часто бывает с вещами, которые вышли до окончательного принятия стандарта. Вы, видимо, просто не следите за реализациями в браузере вещей из WHATWG.
Протокол начинается как HTTP, а дальше работает по чистому TCP. Разработчики спецаиально сделали его похожим на HTTP, чтобы было проще использовать, и иметь меньше проблем с фаерволами, открытыми портами и всем прочим. Даже так скажу: изначально для него предполагался порт 81 (и 815 для шифрованного аналога WSS). Но в дальнейшем решили, что начинать надо по HTTP-шному, поэтому в текущей редакции выбраны 80 и 443 порты.
> prooflink?
Официальная дока: tools.ietf.org/html/draft-hixie-thewebsocketprotocol-68#section-4.1
Вот про SSE:
Значит надо готовить два «вантуза»: один 2-килобайтный, другой 15-секундный?
> Так часто бывает с вещами, которые вышли до окончательного принятия стандарта.
Да. Хотя я понимаю компании, им очень хочется быть первыми и объявить о новой фиче, чтобы привлечь пользователей. Но веб такая отрасль — здесь нельзя быть лучшим в одиночку. Весь веб — это взаимодействие участников на всех уровнях и во всех видах. Что толку от того, что кто-то поддерживает сверхмодный язык типа того же Jscript, если никто больше его не использует?
знали бы вы, сколько раз стандарт переписывался с момента реализации в опере, не называли бы его стандартом; ) Собственно, этого и нельзя делать, потому что он ещё не принят
Поэтому считаю, что оперщики поспешили с реализацией. Легко может возникнуть такая ситуация, что кто-то такой же сверхбыстрый использует это в своем сервисе, который будет постоянно ломаться.
что касается злых фаерволов и проксей: они будут в любом случае, но сейчас они рвут соединения и буферизуют данные, а у WS будут резать лишние заголовки, так что шило меняется на мыло, и разницы большой нет
вы станете спорить, что WS даёт больше возможностей ценой меньшей надёжности?
bolk: Нет, такой возможности нет.
Надеюсь, вы согласны, что SSE даёт больше надёжности, ценой меньшей возможности?
к этому результату мы могли бы прийти намного раньше, если бы вы тогда не стали утверждать, что возможностей у SSE столько же, а просто сказали, что бо́льшая надёжность оправдывает SSE ; )
Last-Event-Id?
Его можно сделать с помощью WebSockets — просто в случае обрыва канала передать номер последнего сообщения и продолжить получать данные.
А сама сессия, тоже должна быть надежнее. Хотя бы из-за отсутствия необходимости в «вантузах» для пробивания проксей.
А закрывать сервер соединение будет только если клиент пошлет определенный запрос? Ололо, заддосить сервера стало еще проще?
Да и как-то не считаю я это великим прогрессом, мир от этого сильно не изменится, просто программисты станут еще ленивее. Я лично хочу сам делать запросы, а не подходить к компьютеру и видеть, что сервер моему клиенту послал пару гигабайт не понятно чего, а клиент ему ответил еще большим :)
Программисты, конечно, станут ленивее. Многие новые технологии придумываются исключительно для удобства программистов. Взять хотя бы языки высокого уровня)
Ну, лень — двигатель прогресса ;)
«Я тут вам гиг хочу прислать, можно?» :)
«Опера» не придумала этот стандарт, это часть стандарта WHATWG: www.whatwg.org/specs/web-apps/current-work/#scs-server-sent
По этому поводу (MMO real-time action app в брайзере) у разработчиков ТанкиОнлайн отличный доклад есть.
Еще мне интересно вот что: как в WebSockets будет реализован load-balancing? Ведь для для существующего веба это делается достаточно просто как раз потому, что он stateless или практически stateless.
Load balancing можно сделать на основе round robin, когда несколько машин будут принимать подключения, после этого, конечно, клиент «привязывается» к конкретному серверу.
Раскидывать подключения можно как с помощью железяки (ну это всегда будет работать), DNS, или же просто установить один приемник, который будет делать 302 редирект на конкретный сервер.
//из печальной беседы о джумле с коллегой.
Вы ничего не перепутали?
А когда появится расширение в браузере, которое будет WebSocket сервером? Тогда Opera Unite RIP?
Пасибо.
2) Думаю, что в случае чего Opera Unite проапгрейдят, и тем невозбранно достигнут желаемого.
Поэтому если автор претендует все же на техническую статьи, а не маркетинговый пиар, то стоило бы подумать об изменении статьи. Не забивайте себе мозг неправильными мыслями, не забивайте ложными концепциями головы другим.
Ну и данная статья — вводная.
XHR — это способ реализации, но опять же не единственный.
Кстати, XHR обозначает XmlHttpRequest, но только XML-ем там давно не пахнет.
И это вы мне говорите?
Нет ни чистого ни грязного AJAX. Есть просто подход при котором обновляется только часть страницы. Причем люди с прямыми руками реализовывали это на iframe+html+javascript еще в конце девяностых прошлого века.
Нельзя сравнивать белое с пушистым, AJAX с WebSockets, подход к написанию приложения с конкретным примером реализации.
Да, вам это интереснее всего говорить :)
Иногда так бывает, что человек очень преуспеет на каком-то направлении, и все новое воспринимается через привычный инструмент, поэтому не понимается и не принимается. Для принятия надо немного перестроить сознание. Точно так же как создание асинхронных сайтов потребовало нового мышления с элементами асинхронности, конкуренции и ситуации гонки. Так же и теперь с полу-асинхронного взгляда на вещи надо перейти к полностью асинхронному. :)
Я с вами соглашусь, что люди делали тоже самое с помощью IFrame уже давно. Но по большому счету (с точки зрения предназначения HTML, Frame и тп.) — это хак — то есть использование инструментов не по назначению. В дальнейшем это было стандартизовано и снабжено доп. фичами в виде XmlHttpRequest. И предназначено для частичного обновления страницы. В дальнейшем возникла необходимость обновлять часто и в неизвестное для клиента время. Пошли лонг-поллинги и прочее.
Но опять же, асинхронность в них довольно однобокая. Например, вы можете отправить одновременно 2 запроса? А 5?
Проблема в том, что принцип «запрос-ответ» все равно лежит в основе всего этого: от ифрейма прошлого века, до новейшего XHR.
Теперь же предлагется честная асинхронность. Уже нет ни «запросов», ни «ответов» — каждый говорит когда ему надо. Поэтому WebSockets не просто новая технология или название яваскриптовых объектов на странице, но еще и новая идеология.
Могу уверить, WebSockets как технология абсолютно не нова. Флеш спокойно позволяет держать сокеты. В обычном сетевом, не веб мире, долгие коннекты вполне себе банальное действо. Но вот оно доползло до HTTP и все, революция. Ничуть. Поэтому я все же настаиваю, что в данном случае WebSockets это не более, чем описание интерфейса для старой технологии созданное для веба. Да, меня как разработчика это не может не радовать, но я то отлично понимаю, что это не вопрос создания новой технологии, а просто вопрос того, сколько крупных игроков поддержит эту реализацию (XHR поддержали очень многие и это стало очень быстро развиваться) и она уйдет в массы. Не более. Написать свое расширение HTTP на самом деле не проблема, возьмем, к примеру, WebDAV, проблема в том, на сколько это будет поддержано другими игроками.
Совершенно верно! TCP-протокол старше нас с вами! Это норма сетевого взаимодействия. А команде telnet, которая позволяет это все делать в консоли — «в обед сто лет». Здесь я не собираюсь с вами спорить, т.к. придерживаюсь той же самой точки зрения.
Несмотря на то, что HTTP бегает поверх TCP, он разработан не для долгих сеансов, а чтобы подключиться, взять документ и освободить ресурсы. Именно в таком порядке: «запрос — ответ(ы)», и никак иначе. Я имею наглость утверждать, что HTTP в принципе синхронный протокол именно по этой причине. Даже в слове AJAX первая буква написана маркетологом. Асинхронный по отношению к чему? К загруженной страничке в браузере, к вызвавшему ява-скрипту, но не по отношению к серверу. Поэтому в аяксе асинхронность половинчатая. Все комет-технологии это только способ улучшить положение, приподнять степень асинхронности. И именно вот сюда — в сетевое взаимодействие сервер-клиент — веб-сокеты приносят честную асинхронность. Потому что все остальное (яваскрипт с коллбеками) уже готово и ждет.
Чуть выше уже выразили мнение, что флеш это хак. И оно имеет под собой почву. Флеш вещь немного инородная по отношению к браузеру, поэтому логично, что он имеет свои сокеты, свой XML-объект и так далее. Очень хорошо, что мы его можем использовать для исправления положения. Но когда мы сможем от него отказаться и использовать нативную поддержку веб-сокетов, будет лучше. Потому что иначе мы будем натыкаться на проблемы с проксями, баннерорезалками, корп. политиками и прочим — обратная сторона самостоятельности флеша.
А я возьму и соглашусь :) И даже выделю курсивом три последних слова в вашей фразе! :)
Мне тут попалось хорошее определение веб-сокетов, которое претендует на звание лучшего: «WebSockets — это TCP для Web».
Согласен. Например, Мозилла уже поддержала эту инциативу, и, полагаю, в следующем фаерфоксе будет эта технология. Может где-то к лету.
Да, хотя и там косяков было предостаточно, вплоть до разных название одного объекта в разных браузерах. Проблема в том, что там решение шло «снизу» — от конкретных разработчиков браузеров, а здесь «сверху» — от разработчиков стандартов. Понятно, что на самом деле это одни и те же люди :) Но в одном случае действуют сами по себе, а в другом — сообща.
http://github.com/gimite/web-socket-js
Так что все броузеры уже поддерживаются.
Вы меня расстроили — ведь я даже указал ее в статье!
Спасибо за пост.
Буду готовить статью о демоне =)
Спасибо!
Приведенный проект phpwebsocket производит стойкое впечатление убогой фигни, кривее написать трудно =)
СОгласен. Это очень примитивный пример, который легко пощупать собственными руками на своем компе. Я смотрел разные реализации, но какие-то сделаны на Руби, какие-то на Erlang в конце концов выбрал ПХП — как язык, который более-менее всем знаком. А значит проще будет поковыряться.
Да, давайте размещу. Пришлите к ней небольшой коммент, как лучше написать про вашу реализацию.
Уже пора думать о ёлках, голова сама просит :)
Вот мы и работаем 24/7… надеюсь до НГ допишем базовую версию сервера и сможем отметить НГ результативно))
А что пишете если не секрет? На чем?
Основная идея помогать людям)
Идей у нас крайне много… а вот человеко-часов на реализацию очень мало.
Пишем на Питоне. В качестве сервака используем Торнадо. Сча вот переписываем его под свои нужды и собираем такой себе мини-фреймворк для проекта. Ибо как мы подитожолили, единственный вменяемый фрейм под высокую нагрузку на Питоне это Твистед. Думали уже писать на нем… но потом вот появился Торнадо, который показал очень неплохие результаты и простоту кода и мы решили не использовать Твистед, а писать свои либы по мере необходимости, что бы полностью понимать почему и как у нас работает приложение.
Еще один веселый прикол, что из нас троих в сетевых технологиях и Питоне разбираюсь только я… и то нада сказать не очень… ибо практики написания такого рода приложений крайне мало. Благо есть много хороших книг и полезных ресурсов.
Посему работаем как рабы на плантации))
Из питонистого хайлоадного я тоже присмотрел торнадо.
Это нормально — ведь нужны разные спецы, им можно поручить что-нить другое. :)
> В отличие от HTTP веб-сокеты не имеют ограничений на время жизни в неактивном состоянии.
Теоретически. Реально в ОС практически всегда установлен Timeout по которому автоматически закрывается сокет.
> Это значит, что больше не надо периодически рефрешить соединение, т.к. его не вправе «прихлопывать» всякие прокси.
Опять теоретически. Когда это станет реальностью, пройдет еще лет 5. А пока что будьте уверены, если у вас корпоративный файрволл — через пару минут ваше соединение завершится.
> Значит, соединение может висеть в неактивном виде и не требовать ресурсов. Конечно, можно возразить, что на сервере будут забиваться TCP-сокеты.
И забьются моментально, т.к. клиент при закрытии соединения не посылает терминального пакета. Сокеты так и останутся висеть в неактивном состоянии.
Реально что приходится делать:
1. Сервер время от времени пингует клиентов, чтобы оборвать неактивные «висящие» сокеты.
2. Опционально клиент тоже может пинговать сервер, и например определять время пинга.
3. Поскольку надежность http-соединения не гарантирована (корпоративные прокси), приходится реализовать механизм автоматического реконнекта.
А в том и соль эволюции технологий, что тоже самое (или чуть лучшее) достигается более простыми средствами, с большей надежностью, безопасносностью, сервисом и тп.
> А пока что будьте уверены, если у вас корпоративный файрволл — через пару минут ваше соединение завершится.
HTTP — да. Но прибивать любое TCP подключение просто через 2 минуты некорректно даже для корпоративного фаервола.
> И забьются моментально, т.к. клиент при закрытии соединения не посылает терминального пакета. Сокеты так и останутся висеть в неактивном состоянии.
Почему не посылает? Это предусмотрено стандартом TCP, если он не посылает, то он работает не по стандарту. Значит, он не клиент, а неведомая хрень.
Чтобы не забивалось надо иметь хорошую цифру в somaxconn и хороший мультиплексор.
> Реально что приходится делать:…
Да, на практике это надо будет сделать. Чтобы учеть даже такие банальные вещи, как случайный отруб инета у клиента (например, если у него модем или еще что-то). В таком случае, нам надо узнать, что он отвалился и дать ему возможность переконнектиться.
Но и это тоже легко реализуется в технологии вебсокетов:
1. Честное отключение вызовет закрытие сокета, которое можно обработать.
2. Если мы при отправке пакета получили ошибку, то сокет надо закрыть.
3. Если отправили пинг и клиент за установленное время не ответил — то так же надо закрыть.
Кстати, благодаря симметричности, логика обработки на серверной и клиентской стороне будет похожа, с той разницей, что клиент может инциировать переподключение.
Но лучше поздно чем никогда!