Длинные опросы (long poll)
Другое название способа - "Очередь ожидающих запросов". Краткая схема такова:
- Отправляется запрос на сервер
- Соединение не закрывается сервером
- Событие отправляется в ответ на запрос
- Клиент тут же отправляет новый ожидающий запрос

Каждый пакет данных, таким образом, означает новое (не учитывая Keep-Alive) соединение,
которое будет открыто столько, сколько нужно, пока сервер не решит прислать информацию.
На практике, соединение обычно переустанавливается раз в 20-30 секунд, чтобы избежать возможных проблем, например с HTTP-прокси.
В отличие от простого поллинга, здесь уведомление о событии приходит гораздо быстрее.
Задержка = установление соединения + передача данных
Такие задержки вполне терпимы в случае, если событий немного, и совершенно незаметны, если обновления с сервера приходят раз в минуту и реже. При активном чате и больших сетевых задержках ("большой ping"), они уже более ощутимы.
- Задержки между событием и уведомлением
- ...но не такие как в поллинге
- Входящий трафик на сервер
Этот метод достаточно удобен в реализации, лишь немного сложнее простого поллинга.
В качестве транспорта можно использовать что угодно - от XMLHTTPRequest до тегов script. Все просто, поэтому пример не рассматриваем.
|
Как я понимаю это способ избавиться от недостатков в реализации XMLHTTPRequest - сброс/очистка устаревшего содержимого в response?
Можно в принципи вообще не разрывать связь, а складывать все в response и при поступлении данных их обрабатывать... ну допустим если у нас "своя сеть", а для сброса переподключаться к серверу.
Поддерживаю вопрос: уверен что возможно обрабатывать данные по мере поступления, раз браузер может принимать такие страницы.
Например в php файле в начале мы ставим:
Таким образом скрипт может выполняться например час. И в течении часа браузер будет выводить поступающие данные.
Так почему мы не можем сделать такой запрос через ajax , и обрабатывать данные по мере поступления? Проблема в том, что тот же jquery позволяет вызывать callback функцию только после полной загрузки документа...
а можно привести пример такого запроса?
желательно на примере чата))
Обычный запрос на сервер. Запрос идет на демон чата, демон чата отвечает на запрос только когда приходит сообщение.
А как же timeout? Если сообщений долго не приходит соответсвенно и демон чата тоже долго не отвечает, выйдет лимит времени и ошибка, прийдется переподклбючаться.
Да, именно так. Так что раз в 30 секунд по-любому новый запрос делается на сервер.
ИМХО оптимальнее отслеживать разрыв соединения и только тогда восстанавливать связь.
30 сек. это очень маленький интервал - да когда есть прокся это оптимально, но если сервер может ждать и дольше
И сколько в среднем длится простой соединения, пока сервер его не закрывает?
и что в течении этого времени предлагается делать? циклически проверять наличие обновлений? какой же сервер это выдержит (при чате с 50-100 посетителями онлайн)?
Простоя нет: соединение закрывается, и тут же открывается новое. Задержка на установление соединения с сервером зависит от канала посетителя. Как правило, это в пределах 5-300мс.
Если идет активный чат с кучей сообщений, то такой способ не очень хорош, а если чат, например, двусторонний (два человека, поэтому не так много сообщений), или просто получение событий с сервера - он работает замечательно.
Я предполагаю, что имелся ввиду простой сервера в ожидании наступления события, т. е. каким образом серверу сделать паузу. Мне самому это очень интересно. Я использую ASP и не знаю, как сделать задержку - ни Sleep, ни setTimeout там нет. Допоможите, пожалуйста.
А можете всё же пример написать, так проще для понимания...
Нужен пример!
Илья Кантор пожалуйста приведите пример!
Пример чего конкретно привести?
Это обычный XMLHTTPRequest.
Лично меня интересует пример обработки long-polling запроса в Java сервере (в частности Jetty). Без написания специальных Continuation-сервлетов здесь не обойтись?
PS: вообще учебник хорош - для начинающего в этом деле - само то!
Но дизайн местами убивает :-) Какое-то время откладывал чтение данного ресурса исключительно из-за визуального отторжения.
можете описать вот этот момент серверного скрипта
Соединение не закрывается сервером
* пока не появится событие
И в чем тогда разница этого метода от частых опросов если каждые 20-30 секунд посылается новый xmlhttprequest?
Разница в том, что событие отсылается на клиент тут же, в виде ответа на "подвисший" XmlHttpRequest.
Кроме того, это одно соединение каждые 20-30-100 секунд, а не одно раз в 5-10.
Илья, спасибо все теперь понятно. Вы тут в комментариях писали (Если идет активный чат с кучей сообщений, то такой способ не очень хорош, а если чат двусторонний, или просто получение событий с сервера - он работает замечательно.)
Что то я тут не понял разницу чата с кучей сообщений и двусторонним чатом. Могли бы вы по подробнее описать этот момент?
Поправил соответствующий комментарий.
Народ, нашли еще один вариант установки устойчивого соединения.
Пишется обычный сокет-сервер на свободный порт (например 2020).
Клиент выполняет HTTP запрос на сокет сервер по его порту отличному от 80 например http://www.host:2020
Протокол HTTP 1/1 предусматривает открытое соединение до закрытия сокета.
Соответственно когда нужно сокет-сервер посылает данные. Получается мини-Apache. По этому варианту на каждого клиента создается свой процесс. Средний Мак тянет до 1200 копий процессов. По этому же варианту может работать локальная версия Веб-интерфейса программы. Получаете локальную версию на том же коде. http://localhost:2020
Кому нужны исходники - пишите gomde(dog)mail.ri
(OpenSource www.buddism.ru/ocrlib)
Илья, Вы на мастер классах говорили, что timeout может быть сколько угодно по времени, даже несколько часов.
Здесь Вы пишете про 30 секунд.
Я сам пробовал на чате написанном на nodeJS сделать timeout больше 30 секунд - не вышло.
Вот пример чата от разработчика nodeJS http://chat.nodejs.org/
В нем тоже timeout 30 секунд.
Возможно я Вас неправильно понял, Вы наверное имели в виду Socket.io - да
там есть возможность держать соединение по времени столько сколько нужно.
Можно дольше делать. Что у вас не вышло, напишите подробнее.
Заработало).
Я раньше тестировал в Firebug для FireFox 3.6 не работало, а сейчас работает, так здорово)))
Даже не знаю баг это был или я что-то не правильно делал.
Но всё таки я где-то слышал, что браузеры должны timeout держать 30 секунд, потом отключаться.
Возможно дело в том, что я использовать кросс-доменный запросы и в качестве транспорта script.
Может быть на script задержка в 30 секунд действует?
Написано:
2. Соединение не закрывается сервером
пока не появится событие
Непонятно как завершить соединение с сервером при закрытии страницы. У меня продолжает висеть соединение после закрытия страницы. Разрывать соединение обязатетьно по таймауту или есть другие способы?
Здравствуйте,
для меня не совсем понятен вопрос с сервером. в чём разница с простым AJAX запросом? толко в том что мы тянем время за которое будет возможность получить эти данные? По сути когда запрос выполняется, то скрип так-же завершается и при новом запуске всё идёт по новой? а как быть если мы пишем свой демон на C++, то мы должны плодить под каждого пользователя поток в котором будет висеть заблокировнное соединение до момента отправки данных или разрыва?
Как отследить изменение на сервере?
Данный способ отлично подходит если необходимо наиболее скорейшее получение события с сервера. При обычном AJAX мы долбим сервер каждые 5-10 секунд. В таком случает если событие произошло в 1-ую секунду после запросы то клиент получит событие только через 4-9 секунд, а ведь в некоторых приложениях это большая задержка (чаты). А в случает с лонг поллингом задержка будет только в момент создания нового соединения что в худшем случает составляет 1-2 секунды а обычно на много меньше, а к тому же это только в том случает если событие произошло в момент создания нового соединения а шанс что это произойдет очень мал
Отправить комментарий
Приветствуются комментарии:- Полезные.
- Дополняющие прочитанное.
- Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.Для остальных вопросов и обсуждений есть форум.