28 апреля 2014 г., 10:27 пользователь Ivan Petrov <[email protected]>написал:
> > Судя по вашему описанию, клиент ведёт себя неадекватно. При реконнекте не > > должно идти много соединений. Вы должны инициировать соединение с > сервером, у > > него есть таймаут, скажем 30 секунд. Если в течение этого времени ничего > не > > пришло, клиент делает XMLHttpRequest.abort и только потом инициирует > новое > > соединение. Никаких 30 одновременно никак не получится. > > Вы видимо вообще с лонгпулингом не работали? > Не, работал и много. Браузерные игры делал. > да примерно так и работает, здесь речь идет уже о том что происходит > ПОСЛЕ XMLHttpRequest.abort. > > а после происходят повторные попытки. > Верно. > > если повторная попытка удачная, то клиент в результате этой удачи > получает все сообщения накопившиеся "для него" за время пока шли > попытки переустановить соединение. > Верно. Вся пачка будет доставлена за один запрос, который последует за обрывом связи. > > ну и вообще смысл работы любого сервера лонгпулинга - хранить > сообщения для клиентов пока те реконнектятся. > если бы не было реконнектов, то получился бы вебсокет. > Верно. Точнее, есть ещё таймаут на стороне сервера, который заставит сервер "забыть" клиента, если он надолго отвалился. И тогда после реконнекта клиент получит уведомление, что его сессия протухла, и надо загрузить всё состояние приложения заново. > далее получается что поскольку с лонгпулингом мы таким образом можем > получить сразу большой пакет событий, то уже *в обработке* этих > событий получается: > > - если событие приводит скажем к изменению цвета кнопки - тут все > просто > - если событие рождает AJAX запрос, то вот тут начинаются проблемы. ибо в > некоторых случаях может получаться пакет AJAX запросов. > А зачем событию рождать AJAX запрос? Я не очень знаю, что у вас за приложение, но, вероятно, этого как раз можно избежать. Если надо запросить 30 дополнительных объектов, то может это сделать одним запросом на сервер? Или доставить их прямо внутри лонгполл-ответа? > вопрос состоит в том что либо мы *в конкретном приложении* придумываем > некие критерии как эти запросы обрабатывать пакетно, > либо видимо можно сформулировать некоторый общий критерий, обобщенную > реакцию самого клиента lp на такие события, как задержки. > > я вопрос тут описал как раз на тему может кто-то продумывал сие на > общеконцептуальном, архитектурном уровне Я так делаю: Когда клиент присоединяется, ему приходит через лонгполл "состояние мира". В играх это текущая локация, список объектов на локации, их координаты. Когда состояние объекта меняется (персонаж передвигается, например), всем подключенным клиентам в той же локации рассылается сообщение "объект 123 движется по траектории 5,7,4,2,6,7,3,2". Каждое сообщение маркируется тегом, в данном случае это будет 123.coord. Если какой-то клиент ещё не успел выгрести предыдущее сообщение с тем же тегом, то старое заменяется новым. Такие образом, после таймаута клиент не получит 100500 пропущенных перемещений, а только самое свежее. Если же клиент отваливается очень надолго, то через несколько минут сервером фиксируется таймаут, а персонажа выкидывает из игры. Если соединение восстановилось, то сервер обрабатывает событие "игрок вошёл в игру", на клиент посылается пакет "очистить всё", а затем полный перечень всеъ объектов на локации и т.д, как будто новый клиент подключился.
-- Moscow.pm mailing list [email protected] | http://moscow.pm.org
