[Moscow.pm] а вот кто с лонгпулингом работает?

Alexander Lourier aml на rulezz.ru
Пн Апр 28 03:10:43 PDT 2014


28 апреля 2014 г., 10:27 пользователь Ivan Petrov
<i.petro.77.00 на gmail.com>написал:

> > Судя по вашему описанию, клиент ведёт себя неадекватно. При реконнекте не
> > должно идти много соединений. Вы должны инициировать соединение с
> сервером, у
> > него есть таймаут, скажем 30 секунд. Если в течение этого времени ничего
> не
> > пришло, клиент делает XMLHttpRequest.abort и только потом инициирует
> новое
> > соединение. Никаких 30 одновременно никак не получится.
>
> Вы видимо вообще с лонгпулингом не работали?
>

Не, работал и много. Браузерные игры делал.


> да примерно так и работает, здесь речь идет уже о том что происходит
> ПОСЛЕ XMLHttpRequest.abort.
>
> а после происходят повторные попытки.
>

Верно.


>
> если повторная попытка удачная, то клиент в результате этой удачи
> получает все сообщения накопившиеся "для него" за время пока шли
> попытки переустановить соединение.
>

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


>
> ну и вообще смысл работы любого сервера лонгпулинга - хранить
> сообщения для клиентов пока те реконнектятся.
> если бы не было реконнектов, то получился бы вебсокет.
>

Верно. Точнее, есть ещё таймаут на стороне сервера, который заставит сервер
"забыть" клиента, если он надолго отвалился. И тогда после реконнекта
клиент получит уведомление, что его сессия протухла, и надо загрузить всё
состояние приложения заново.


> далее получается что поскольку с лонгпулингом мы таким образом можем
> получить сразу большой пакет событий, то уже *в обработке* этих
> событий получается:
>
>  - если событие приводит скажем к изменению цвета кнопки - тут все
>    просто
>  - если событие рождает AJAX запрос, то вот тут начинаются проблемы. ибо в
> некоторых случаях может получаться пакет AJAX запросов.
>

А зачем событию рождать AJAX запрос? Я не очень знаю, что у вас за
приложение, но, вероятно, этого как раз можно избежать. Если надо запросить
30 дополнительных объектов, то может это сделать одним запросом на сервер?
Или доставить их прямо внутри лонгполл-ответа?


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


Я так делаю:
Когда клиент присоединяется, ему приходит через лонгполл "состояние мира".
В играх это текущая локация, список объектов на локации, их координаты.
Когда состояние объекта меняется (персонаж передвигается, например), всем
подключенным клиентам в той же локации рассылается сообщение "объект 123
движется по траектории 5,7,4,2,6,7,3,2". Каждое сообщение маркируется
тегом, в данном случае это будет 123.coord. Если какой-то клиент ещё не
успел выгрести предыдущее сообщение с тем же тегом, то старое заменяется
новым. Такие образом, после таймаута клиент не получит 100500 пропущенных
перемещений, а только самое свежее.
Если же клиент отваливается очень надолго, то через несколько минут
сервером фиксируется таймаут, а персонажа выкидывает из игры. Если
соединение восстановилось, то сервер обрабатывает событие "игрок вошёл в
игру", на клиент посылается пакет "очистить всё", а затем полный перечень
всеъ объектов на локации и т.д, как будто новый клиент подключился.
----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mail.pm.org/pipermail/moscow-pm/attachments/20140428/e29c76e1/attachment.html>


Подробная информация о списке рассылки Moscow-pm