devconf2013: Особенности применения websocket на примере работы...

Post on 08-May-2015

1.105 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

Краткий обзор существующих решений Что такое web sockets обеспечение работы web sockets на стороне сервера основной механизм работы с web sockets в PHP Нюансы использования

TRANSCRIPT

Особенности применения Websocket

на примере работы в ERP Фролов Александр

14.06.2013г.

Актуальность данных

• Данные на странице — устаревают;• основании устаревших данных можно принять не верное

решение;• Не верное решение ведёт в конечном счёте к финансовым

потерям, если это приложение решает бизнес задачи.• Выход? Нужно получать данные от сервера в момент их

поступления на сервер;• Нужно иметь возможность инициировать отправку

данных сервером.

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

• Первый тривиальный способ — запрашивать каждые n секунд сервер о новых данных. При этом чем чаще — тем быстрее получаем обновление данных.

• Простой подсчёт показывает: в ERP системе за сутки будет генерировать 2,5 миллиона запросов. КПД от работы системы — стремится к нулю.

Ограничения: согласно спецификации HTTP 1.1

браузер не должен иметь более двух соединений одновременно

• Если открыто более двух страниц в браузере очень вероятны случаи, когда запросы на обновление не проходят;

• Применение других способов, отличных от простых запросов на обновления так же требует учитывать это обстоятельство;

Comet (программирование)

• Модели работы веб приложений, при которых постоянное HTTP соединение позволяет веб-серверу отправлять (push) данные браузеру без дополнительного запроса со стороны браузера, называют Comet технологиями, а приложения, которые реализуют такую модель — comet приложениями.

• Благодаря comet-приложениям клиент в режиме реального времени может взаимодействовать с сервером, опираясь на постоянное или long polling соединение HTTP.

Реализации comet технологий

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

• Long polling (длительное соединения): открывается соединение и ожидается ответ по таймауту или до таймаута, после чего соединение переоткрывается

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

сервером.

Скрытый IFRAMEПостоянно в IFRAME шлются данные, например, строки с

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

XMLHttpRequest

У ряда браузеров (FF, WebKit, IE10) имеется возможность получать multipart response — ответ порциями, тем самым очередную порцию отсылаем тогда, когда нужно серверу. Особого распространения не получило.

Ajax с long polling

Браузер делает Ajax запрос на сервер, который остается открытым, пока сервер не отправит данные. По таймауту пересоздается соединение.

Script tag long polling

Подгружается динамически javascript файлы, в которых передаются данные по мере их поступления. Как только один файл «загрузился», подгружается следующий файл.

WebSocket

WebSocket - веб-технология, обеспечивает полнодуплексный канал связи через одно соединение TCP. Протокол WebSocket был стандартизирован IETF RFC 6455 в 2011 году. WebSocket соответствует стандартам W3C.

Базовое использование WebSocket на стороне клиента:

<script>

ws = new WebSocket("ws://site.com/ws");

// обработка события, при установки соединения

ws.onopen = function() { alert("Connection opened...") };

// обработка события, при закрытии соединения

ws.onclose = function() { alert("Connection closed...") };

// обработка события получения сообщение через веб-сокет

ws.onmessage = function(e) { alert(e.data); };

</script>

Немного деталей :)

Процесс открытия WS выглядит на данный момент следующим образом.

В начале идёт HTTP-запрос:

GET /ws HTTP/1.1

Host: site.com

Upgrade: websocket

Connection: Upgrade

Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==

Sec-WebSocket-Protocol: chat

Sec-WebSocket-Version: 13

Origin: http://site.com

Если сервер поддерживает WS, то то ответ будет:

HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept:

HSmrc0sMlYUkAGmm5OPpG2HaGWk=Sec-WebSocket-Protocol: chat

Sec-WebSocket-Key содержит случайное значение,закодированное Base64.

Sec-WebSocket-Accept вычисляется путём конкатенации Sec-WebSocket-Key и «magic string»:

258EAFA5-E914-47DA-95CA-C5AB0DC85B11

$SecWebSocketAccept = base64_encode(sha1($SecWebSocketKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));

Существует две модификации протокола: ws:// и wss://, это по смыслу почти как http:// и https://, то есть wss:// - шифрованное соединение.

Формат передаваемых текстовых данных

0x00 <строка в кодировке UTF-8> 0xFF

просто строка текста — последовательность байт, к которой спереди приставлен нулевой байт 0x00, а в конце — 0xFF. И все — никаких заголовков, метаданных.

Передача и бинарных данных

Длина записывается по следующим правилам: Каждый байт в указании длины рассматривается по частям: самый старший бит указывает является ли этот байт последним (0) либо же за ним есть другие (1), а младшие 7 битов содержат собственно данные.

0x80 <длина - один или несколько байт>

<тело сообщения>

1 0 0 0 1 1 1 01 0 0 0 0 1 1 0 0 0 0 1 0 1 1 0

Какими браузерами поддерживается?

Protocol IE FF FF(android)

Chrome Safari Opera

hixie-75 4 5.0.0

hixie-76hybi-00

4 6 5.0.1 11

7 hybi-07 6

8 hybi-10 7 7 14

13 RFC 6455 10 11 11 16 6 12.10

Организации работы WS

Различные реализации серверов на многих платформах: node.js, Pyton, Ruby on Rails, PHP...

Из PHP Open Source проектов можно отметить довольно динамично развивающийся проект phpDeamon. Но это универсальный всеядный комбайн.

Но в реальности используем более легкую реализацию, которую проще проверить и адаптировать под свои нужды.(https://github.com/lemmingzshadow/php-websocket)

Принцип работы WS сервера на php

- запуск в цикле опроса открытых портов.

while(true) {

foreach($sockets as $socket) {

// read socket

$data = readBuffer($socket);

process_data($cleint[(int)$socket], $data);

}

}

Обычная схема работы

БДWSК

Схема быстрого внедрения WS

БД

WS

К2

Кn

К1

WSS

Ajax

mess

mess

mess

mess

Mess — сообщение Об изменениях, для всех одно и тоже, фильтрация «нужен / не нужен» или на сторонеклиента или решение обОтправки mess принимаетWSS исходя из типа страницы на строне клиента.

Продвинутая схема использования WS

БД

WS

К2

Кn

К1

WSS

Ajax

mess

mn

m2

m1

mess — сообщение об измененияхM1, M2, … Mn — подготовленные для каждого типа страниц сообщения, включающие все специфические данные. Не достающие данные добираются из БД.

Полная интеграция WS

БД

WS

К2

Кn

К1

WSS

HTTP

m0

mn

m2

m1

Конкурирующие запросы• С ростом количества запросов может быть ситуация,

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

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

• Так же нужна временная метка о начале работы с данными, то есть когда пришли данные, которые отредактировали;

• Две временные метки позволяют сравнить данные, которые меняем с данными которые находятся в БД, а так же их «свежесть» и в случае чего не допустить перезатирания новых данных — старыми. При этом клиенту, приславшего конфликтный запрос — отправлять уведомление с просьбой проверки данных + обновленные данные.

Стоит ли использовать более серьёзный подход?

• Можно использовать систему разделения ресурсов, флаги, семафоры...

• Внедрение связано со значительным усложнением всей системы;

• От пользователе потребуются дополнительные усилия в работе;

• Необходимо четко очень реальную необходимость внедрения.

Пишите логи

В обязательном порядке записываете в логах обо всех изменениях в системе: • кто• когда• что• старое значение• новое значение

Собирайте мусор в WSS

WSS представляет собой один работающий процесс по приему, обработке и отправке сообщений. Со временем не используемые переменные постепенно забивают память вплоть максимально возможного лимита для php процесса. Чтобы этого не случилось необходимо подчищать за собой переменные и объекты (gc_enble(); gc_collect_cycles(); gc_disable; )

Перегружайте WSS иногда :)

gc_collect_cycles() помогает, но объем используемой памяти всё равно может неуклонно расти.

Поэтому проверяйте объём используемой памяти, и в случае превышения определенного лимита инициируйте перезагрузку WSS.

Пример упрощенного кода ядра WSS

$flag = true;While ($flag) { If (time() - $time_last_check >= 60 сек) { If (get_file_flag() == 1) { $flag = false; } else if (memory_get_peak_usage()/1024/1024

>= ini_get("memory_limit") * 0.8) { send_notice(); set_timer_to_reboot(); $flag = false(); } }}

Возможности «виртуального» кэша

• Так как процесс обрабатывающий сообщения один, то и сохраняя данные в определенный массив/объект можно получить нечто на подобие кэша с актуальными данными;

• Следует учитывать ограничения на объём памяти и не забывать подчищать такой кэш.

• Определив экспериментальным путем суточные потребности ERP системы были увеличены лимиты с 128Мб, до 1Гб памяти для WSS, тем самым все необходимые для работы данные в результате находились в кэше.

• В PHP 5.3.0 можно указывать в php.ini memory_limit 1G

Ссылки на ресурсы, статьи, GitHub

http://en.wikipedia.org/wiki/Comet_(programming)http://en.wikipedia.org/wiki/WebSockethttps://github.com/nicokaiser/php-websockethttp://nginx.com/news/nginx-websockets.htmlhttps://github.com/disconnect/apache-websocket https://github.com/kakserpom/phpdaemon https://github.com/nicokaiser/php-websocket https://github.com/hoaproject/Websocket https://github.com/lemmingzshadow/php-websocket

Докладчик: Фролов Александрalex.frolov@gmail.com

@alex__frolovhttps://www.facebook.com/frolov.alexander

top related