Javascript.RU

Длинные опросы (long poll)

Update: Более новый материал по этой теме находится по адресу https://learn.javascript.ru/xhr-longpoll.

Другое название способа - "Очередь ожидающих запросов". Краткая схема такова:

  1. Отправляется запрос на сервер
  2. Соединение не закрывается сервером
    • пока не появится событие
  3. Событие отправляется в ответ на запрос
  4. Клиент тут же отправляет новый ожидающий запрос

Каждый пакет данных, таким образом, означает новое (не учитывая Keep-Alive) соединение,
которое будет открыто столько, сколько нужно, пока сервер не решит прислать информацию.

На практике, соединение обычно переустанавливается раз в 20-30 секунд, чтобы избежать возможных проблем, например с HTTP-прокси.

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

Задержка = установление соединения + передача данных

Такие задержки вполне терпимы в случае, если событий немного, и совершенно незаметны, если обновления с сервера приходят раз в минуту и реже. При активном чате и больших сетевых задержках ("большой ping"), они уже более ощутимы.

  • Задержки между событием и уведомлением
  • ...но не такие как в поллинге
  • Входящий трафик на сервер

Этот метод достаточно удобен в реализации, лишь немного сложнее простого поллинга.

В качестве транспорта можно использовать что угодно - от XMLHTTPRequest до тегов script. Все просто, поэтому пример не рассматриваем.


Автор: fast, дата: 20 марта, 2008 - 10:04
#permalink

Как я понимаю это способ избавиться от недостатков в реализации XMLHTTPRequest - сброс/очистка устаревшего содержимого в response?

Можно в принципи вообще не разрывать связь, а складывать все в response и при поступлении данных их обрабатывать... ну допустим если у нас "своя сеть", а для сброса переподключаться к серверу.


Автор: __Levsha (не зарегистрирован), дата: 26 января, 2011 - 07:23
#permalink

Поддерживаю вопрос: уверен что возможно обрабатывать данные по мере поступления, раз браузер может принимать такие страницы.

Например в php файле в начале мы ставим:

ob_implicit_flush();
set_time_limit(0);

Таким образом скрипт может выполняться например час. И в течении часа браузер будет выводить поступающие данные.

Так почему мы не можем сделать такой запрос через ajax , и обрабатывать данные по мере поступления? Проблема в том, что тот же jquery позволяет вызывать callback функцию только после полной загрузки документа...


Автор: constantant, дата: 17 ноября, 2008 - 17:18
#permalink

а можно привести пример такого запроса?
желательно на примере чата))


Автор: Илья Кантор, дата: 18 ноября, 2008 - 10:16
#permalink

Обычный запрос на сервер. Запрос идет на демон чата, демон чата отвечает на запрос только когда приходит сообщение.


Автор: Алексей_hose (не зарегистрирован), дата: 12 февраля, 2009 - 14:36
#permalink

А как же timeout? Если сообщений долго не приходит соответсвенно и демон чата тоже долго не отвечает, выйдет лимит времени и ошибка, прийдется переподклбючаться.


Автор: Илья Кантор, дата: 13 февраля, 2009 - 10:27
#permalink

Да, именно так. Так что раз в 30 секунд по-любому новый запрос делается на сервер.


Автор: goldserg, дата: 26 апреля, 2010 - 10:28
#permalink

ИМХО оптимальнее отслеживать разрыв соединения и только тогда восстанавливать связь.
30 сек. это очень маленький интервал - да когда есть прокся это оптимально, но если сервер может ждать и дольше


Автор: Ajaxy (не зарегистрирован), дата: 20 апреля, 2009 - 00:14
#permalink

И сколько в среднем длится простой соединения, пока сервер его не закрывает?
и что в течении этого времени предлагается делать? циклически проверять наличие обновлений? какой же сервер это выдержит (при чате с 50-100 посетителями онлайн)?


Автор: Илья Кантор, дата: 20 апреля, 2009 - 13:04
#permalink

Простоя нет: соединение закрывается, и тут же открывается новое. Задержка на установление соединения с сервером зависит от канала посетителя. Как правило, это в пределах 5-300мс.

Если идет активный чат с кучей сообщений, то такой способ не очень хорош, а если чат, например, двусторонний (два человека, поэтому не так много сообщений), или просто получение событий с сервера - он работает замечательно.


Автор: AL_ (не зарегистрирован), дата: 18 ноября, 2009 - 16:10
#permalink

Я предполагаю, что имелся ввиду простой сервера в ожидании наступления события, т. е. каким образом серверу сделать паузу. Мне самому это очень интересно. Я использую ASP и не знаю, как сделать задержку - ни Sleep, ни setTimeout там нет. Допоможите, пожалуйста.


Автор: mycoding, дата: 18 января, 2010 - 17:00
#permalink

А можете всё же пример написать, так проще для понимания...


Автор: Rol1k, дата: 3 февраля, 2010 - 19:19
#permalink

Нужен пример!


Автор: HelpeR, дата: 15 марта, 2010 - 19:48
#permalink

Илья Кантор пожалуйста приведите пример!


Автор: Илья Кантор, дата: 15 марта, 2010 - 19:57
#permalink

Пример чего конкретно привести?

Это обычный XMLHTTPRequest.


Автор: nukisman (не зарегистрирован), дата: 26 апреля, 2011 - 16:12
#permalink

Лично меня интересует пример обработки long-polling запроса в Java сервере (в частности Jetty). Без написания специальных Continuation-сервлетов здесь не обойтись?

PS: вообще учебник хорош - для начинающего в этом деле - само то!
Но дизайн местами убивает :-) Какое-то время откладывал чтение данного ресурса исключительно из-за визуального отторжения.


Автор: HelpeR, дата: 17 марта, 2010 - 09:26
#permalink

можете описать вот этот момент серверного скрипта

Соединение не закрывается сервером

* пока не появится событие
И в чем тогда разница этого метода от частых опросов если каждые 20-30 секунд посылается новый xmlhttprequest?


Автор: Илья Кантор, дата: 17 марта, 2010 - 20:30
#permalink

Разница в том, что событие отсылается на клиент тут же, в виде ответа на "подвисший" XmlHttpRequest.

Кроме того, это одно соединение каждые 20-30-100 секунд, а не одно раз в 5-10.


Автор: HelpeR, дата: 19 марта, 2010 - 22:15
#permalink

Илья, спасибо все теперь понятно. Вы тут в комментариях писали (Если идет активный чат с кучей сообщений, то такой способ не очень хорош, а если чат двусторонний, или просто получение событий с сервера - он работает замечательно.)
Что то я тут не понял разницу чата с кучей сообщений и двусторонним чатом. Могли бы вы по подробнее описать этот момент?


Автор: Илья Кантор, дата: 20 марта, 2010 - 01:51
#permalink

Поправил соответствующий комментарий.


Автор: mycoding, дата: 11 мая, 2011 - 08:19
#permalink

Илья, Вы на мастер классах говорили, что timeout может быть сколько угодно по времени, даже несколько часов.
Здесь Вы пишете про 30 секунд.

Я сам пробовал на чате написанном на nodeJS сделать timeout больше 30 секунд - не вышло.
Вот пример чата от разработчика nodeJS http://chat.nodejs.org/
В нем тоже timeout 30 секунд.

Возможно я Вас неправильно понял, Вы наверное имели в виду Socket.io - да
там есть возможность держать соединение по времени столько сколько нужно.


Автор: Илья Кантор, дата: 11 мая, 2011 - 17:20
#permalink

Можно дольше делать. Что у вас не вышло, напишите подробнее.


Автор: mycoding, дата: 15 мая, 2011 - 10:28
#permalink

Заработало).
Я раньше тестировал в Firebug для FireFox 3.6 не работало, а сейчас работает, так здорово)))
Даже не знаю баг это был или я что-то не правильно делал.

Но всё таки я где-то слышал, что браузеры должны timeout держать 30 секунд, потом отключаться.
Возможно дело в том, что я использовать кросс-доменный запросы и в качестве транспорта script.
Может быть на script задержка в 30 секунд действует?


Автор: Гость (не зарегистрирован), дата: 24 мая, 2011 - 07:58
#permalink

Написано:

2. Соединение не закрывается сервером
пока не появится событие

Непонятно как завершить соединение с сервером при закрытии страницы. У меня продолжает висеть соединение после закрытия страницы. Разрывать соединение обязатетьно по таймауту или есть другие способы?


Автор: Risa (не зарегистрирован), дата: 19 ноября, 2011 - 20:29
#permalink

Здравствуйте,

для меня не совсем понятен вопрос с сервером. в чём разница с простым AJAX запросом? толко в том что мы тянем время за которое будет возможность получить эти данные? По сути когда запрос выполняется, то скрип так-же завершается и при новом запуске всё идёт по новой? а как быть если мы пишем свой демон на C++, то мы должны плодить под каждого пользователя поток в котором будет висеть заблокировнное соединение до момента отправки данных или разрыва?


Автор: RigFox (не зарегистрирован), дата: 4 февраля, 2012 - 21:44
#permalink

Данный способ отлично подходит если необходимо наиболее скорейшее получение события с сервера. При обычном AJAX мы долбим сервер каждые 5-10 секунд. В таком случает если событие произошло в 1-ую секунду после запросы то клиент получит событие только через 4-9 секунд, а ведь в некоторых приложениях это большая задержка (чаты). А в случает с лонг поллингом задержка будет только в момент создания нового соединения что в худшем случает составляет 1-2 секунды а обычно на много меньше, а к тому же это только в том случает если событие произошло в момент создания нового соединения а шанс что это произойдет очень мал


Автор: 1lider, дата: 30 сентября, 2015 - 16:06
#permalink

Добрый вечер. Хотел было воспользоваться данной технологией. Но на одном из форумов мне сообщили о том, будто Long poll съедает много ресурсов сервера. Так ли это?


Автор: Python-программист (не зарегистрирован), дата: 13 января, 2016 - 21:46
#permalink

Да, long polling съедает ресурсы сервера при большом количестве одновременно использующих "сервис" (чят или что-нибудь другое) клиентов, хотя бы потому что приходится поддерживать большое количество TCP-соединений.

Вообще long polling - это плохая практика. Её не следует использовать, если только вы не уверены, что вам ну уж точно он нужен.

КА


Автор: Дмитрий Cian (не зарегистрирован), дата: 12 марта, 2016 - 11:50
#permalink

Ну ведь вконтакте использует его.
Вконтакте Api


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
10 + 9 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum