Pull to refresh

WebSocket: будущее уже здесь!

Reading time 3 min
Views 14K
Сегодня я вкратце расскажу о технологии WebSocket, о предпосылках к её появлению, о текущих проблемах и об их решениях.

Предпосылки


С тех пор как проектировалcя протокол HTTP утекло много воды, и прошли те времана когда Javascript использовался лишь для падающих снежинок на фоне. Вскоре появилась потребность дополнительного обмена данными с сервером, для этого придумали AJAX (сначала через теги iframe и script, затем придумали XMLHttpRequest). Однако, все эти способы подразумевают что передача данных должна инициироваться клиентом. Конечно, всем известны чаты на бесконечно загружаемых frame'ах, однако это всё лишь костыли, которые к тому же создавали большую нагрузку на сервер, из-за несовершенства тех инструментов, которые применялись при разработке. Каждый пользователь съедал процесс на сервере под себя.
В связи с вынужденными мерами разработчиков браузеров по обеспечению безопасности, iframe и XMLHttpRequest не позволяют обмениваться данными с доменами, отличными от домена текущего документа. Существует хаки типа XhrIframeProxy, который образует поток данных между документами используя Историю. Однако, всё это шито белыми нитками.
Достаточно хорошим вариантом является long-polling — метод при котором броузер шлет последовательные запросы, и каждый запрос «висит» пока не в него не поступит пакет данных. Однако, внушительным минусом является большой overhead по трафику и кол-ву соединений.
Главным недостатком этих методов является сложность и муторность конечной разработки, которая представляет собой месиво из полезной логики и низкоуровневой лапши. Таким образом, человек не обладающий твердыми знаниями не может без осложнений реализовать передачу данных по инициативе сервера.

Was ist das?


И вот, наступил 2009 год, 23 апреля. Появился черновик документа под названием «The Web Sockets API», который положил начало конца всех бед. В нем был описан объект доступный из Javascript, который обладает следующими особенностями:
— Origin-based cross-domain policy (политикой безопасности основанной на передаче Orgin) — то есть подключиться мы можем с любой страницы к любому серверу, и он уже сам решит исходя из Orgin'а (адреса документа) надо ли ему это счастье.
— Низкий overhead по трафику.
— Возможность используя одно соединение выполнять передачу данных в обе стороны
— На данный момент нативно поддерживается только в Google Chrome 4+ stable и Safari 5, обещано в Mozilla Firefox 3.7 и IE 9.

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


Варианты:

1. Flash-эмулятор (http://github.com/gimite/web-socket-js)
Минусы: код УГ, не у всех есть флеш, у некоторых стоят flashblock-плагины.

2. Использовать iframe (бесконечную загрузку iframe) и long-polling (ожидание-перезапрос,....).
Минусы: Реализовать три различных транспорта на уровне приложения и наладить межпроцессную коммуникацию — весьма нетривиальная задача.

Чип и Дэйл спешат на помощь


Обдумав ситуацию, я решил что нужен фреймворк удовлетворяющий следующим требованиям:
— Абстракция API от разных транспортов (native websocket, flash websocket, comet, long-polling) как на сервере, так и на клиенте.
— Асинхронность: 1 процесс на сервере должен одновременно поддерживать множество соединений с клиентами.
— Javascript-клиент должен автоматически адаптироваться под броузер, наличие Flash, тип соединения пользователя (direct, proxy, и т.д.).

Дело было вечером, делать было нечего.
Пример того что получилось — http://loopback.su/websocket/ (если упадет не обессудьте, стоит под столом дома).
Серверное приложение тут.
Работает во всех броузерах вплоть до IE 6. Серверная реализация — модули к phpDaemon. Всё вместе можно вытянуть с github.
Главным преимуществом данного подхода является то что вам не нужно думать о том какой у клиента броузер, когда вы пишете клиент-серверное приложение, вы просто пишете так как будто WebSocket у всех нативный.
При желании, серверную часть можно переписать и на другие языки программирования.
Tags:
Hubs:
+54
Comments 122
Comments Comments 122

Articles