#ajax #jquery #node.js #long-polling
#ajax #jquery #node.js #длительный опрос
Вопрос:
Один из запросов AJAX к моему node.js сервер иногда может занимать более двух минут. Я обнаружил, что, когда сервер занимает больше двух минут, клиент повторно отправляет запрос AJAX. Это привело к тому, что сервер еще больше увяз, поскольку он запустил второй дорогостоящий процесс.
Чтобы обойти это, я внедрил решение с длительным опросом на сервере. Клиент выполняет ajax-вызов функции проверки на сервере, которая просто проверяет, завершен ли процесс, перепроверяет каждые пять секунд и возвращается клиенту, когда это будет сделано.
Тем не менее, у меня все еще есть вариант двухминутной проблемы. Второй вызов проверки AJAX все еще выполняется через две минуты. Затем выполняются обе проверки, и кажется, что только новая проверка будет передана обратно клиенту.
Каков наилучший способ решения этой проблемы?
- Есть ли способ настроить или отключить двухминутную повторную отправку ajax?
- Есть ли лучший способ управлять последующими повторяющимися запросами к серверу?
- Нужно ли мне устанавливать тайм-аут на клиенте, а не на сервере?
Я использую вызовы jQuery AJAX, а node.js сервер в браузере Chrome
ОБНОВЛЕНИЕ: сnode.js документы, «время ожидания всех входящих подключений по умолчанию составляет 2 минуты». Меня все еще интересуют предложения о наилучшей практике кодирования длительных запросов сервера, когда клиенту не нужно ничего знать, пока сервер не завершит работу.
Ответ №1:
Чтобы было ясно, что происходит:
- Клиент отправляет запрос «сделай это для меня …»
- Код узла запускает асинхронную операцию (или несколько связанных вместе)
- Проходит две минуты
- Время ожидания HTTP-запроса истекло
- Клиент повторно отправляет запрос
- Теперь выполняются два запроса
- И так далее, пока не будет выполнено множество запросов
Кажется, я слышал, что это называется «эффектом dogpile». Я не знаю ни одной стандартной библиотеки в node.js или jQuery, чтобы помочь вам, хотя кто-то начал работу над кэширующим прокси, чтобы помочь с этим в случае, когда ответ будет «кэшируемым»:
https://github.com/simonw/dogproxy
Итак, вам придется разработать свою собственную систему, чтобы обойти это.
Существуют разные способы обработки пакетных заданий, и часто это зависит от характера задания.
Что я чаще всего видел для задач, которые занимают много времени, так это то, что API сразу возвращает идентификатор для задания, а затем клиент использует опрос (или длительный опрос), чтобы дождаться завершения задания. Вам понадобится какая-то база данных для хранения состояния (% завершения) и результата задания, которая позволит клиенту дождаться изменения этого статуса. Это также может позволить вам «отменить» задание, хотя в этом случае серверный код должен периодически проверять, было ли оно отменено.
Просто имейте в виду, что где бы вы ни хранили статус задания, он должен быть общим для всех узлов кластера, если приложение масштабируется или будет расширено позже. Для этого вы могли бы использовать какую-нибудь высокоскоростную облегченную систему хранения данных, такую как memcached или redis.
Комментарии:
1. Спасибо, что четко объяснили, на чем я спотыкался. Необходимость проводить опрос кажется несоответствием в асинхронной философии узла.
2. Ожидаете ли вы увидеть второй запрос (повторную попытку) в инспекторе Chrome? У меня такое же поведение, описанное выше, при повторной попытке через 2 минуты, но нет указаний на то, повторяет ли это клиент или сервер.
3. Эмиль, я не думаю, что сервер вообще способен инициировать повторную попытку на клиенте — как только соединение сбрасывается, клиент должен повторно подключиться сам. Таким образом, он ДОЛЖЕН отображаться в инспекторе Chrome, если вы записываете сетевые события. Однако, если бы повторная попытка выполнялась каким-либо промежуточным прокси, вы бы не увидели ее на клиенте и не имели бы над ней никакого контроля. Обычно не получается заставить клиента ждать завершения работы сервера более пары секунд из-за ненадежного mdeium HTTP и Интернета в целом без состояния.
4. Пол: Это противоречит философии асинхронности. В идеальном асинхронном мире вы бы предоставили серверу URL для отправки ответа вместо ожидания или опроса ответа. К сожалению, в Интернете существует значительная асимметрия между клиентами и серверами, когда дело доходит до «достижимости», поэтому серверу очень сложно перезвонить клиенту (при условии, что javascript даже предоставил механизм для этого). Длительный опрос работает нормально и не требует больших дополнительных затрат. Эти длительные операции должны быть довольно редкими для большинства приложений.