#jquery #servlets #jakarta-ee #comet #long-polling
#jquery #сервлеты #джакарта-ee #comet #длительный опрос
Вопрос:
Здесь я просмотрел краткий обзор реализации Servlet 3.0 server push и ушел с большим количеством вопросов, чем пришел. Вопросы связаны с моим вариантом использования: внедрение динамической системы уведомлений среди «друзей», а-ля Facebook. Концептуально размышляя о проблеме, я бы подошел к ней следующим образом:
- Поместите бесконечный цикл jQuery на каждую страницу, содержащий код для отправки запроса XMLHttpRequest «get» на сервер
- Разрешить серверу сохранять объекты запроса / ответа, относящиеся к этим типам XMLHttpRequests, на карте с областью приложения (с помощью AsyncContext и .startAsync()), вводимые идентификатором веб-сайта пользователя
- Всякий раз, когда пользователь выполняет действие, которое порождает уведомление, запрашивает у карты в области приложения идентификаторы друзей пользователя и, используя хранящиеся там объекты ответа, отправляет уведомление каждому другу.
- Каждый из друзей получает уведомление, и бесконечный цикл на страницах, на которых они находятся, снова выдает XMLHttpRequests (из-за бесконечного цикла)
Предполагая, что моя система концептуально исправна (и если это не так, пожалуйста, скажите мне, что не так), есть пара проблем, которые я вижу с этой системой:
-
Что происходит с парой запрос / ответ в map после использования ответа? Должен ли я вручную удалить его с карты или дождаться, пока цикл на стороне клиента отправит другой запрос, чтобы сохраненная пара объектов запроса / ответа могла быть заменена парой, связанной с новым XMLHttpRequest? В ссылке выше используются слова «зафиксированный» и «незафиксированный» для обозначения объектов ответа. Может кто-нибудь объяснить, что означают эти слова в данном контексте (у меня такое чувство, что они связаны с долговечностью объектов ответа)?
-
Что произойдет, если двое или более друзей пользователя совершат действия, которые вызывают уведомления в одно и то же время? Для каждого пользователя хранится только одна пара запрос / ответ. Какое бы действие друга ни произошло, чтобы найти пару запрос / ответ соответствующего пользователя, уведомление отправляется этому пользователю, но как насчет действий других друзей? Если все они происходят одновременно, то у других действий не будет пары запрос / ответ, которую можно использовать для отправки уведомления, пока пользователь не отправит другой XMLHttpRequest для сохранения на карте. Предположительно, другие действия проанализируют карту и либо не найдут запись для этого пользователя (поскольку она была удалена вручную после того, как другое действие использовало ответ), либо найдут «устаревший» объект запроса / ответа, который уже использовался. Я предполагаю, что объект response не может использоваться для двух разных ответов, так как бы кто-нибудь исправил это?
-
Что произойдет, если пользователю отправляется уведомление, когда пользователь переключает страницы? Если мы рассматриваем полностью загруженную веб-страницу как открытое окно для получения запросов на уведомление, а загружаемую — как закрытое окно (поскольку оно не может получать и обрабатывать ответы на запросы XMLHttpRequests, отправленные предыдущей страницей), уведомления, отправленные в течение этого периода времени, будут потеряны. Могу ли я что-нибудь сделать, кроме запроса базы данных о новых действиях и генерации уведомлений таким образом при загрузке страницы?
-
Наконец, что происходит, когда пользователь переходит с сайта и сеанс истекает? Ожидается ли, что мы будем периодически выполнять итерации по карте и удалять запросы, связанные с отсутствием существующих сеансов?
Извините, если это было долгое чтение. Даже если вы можете ответить только на один из вышеупомянутых вопросов, это помогло бы!
Ответ №1:
-
Ответ сохраняется, вероятно, до истечения времени ожидания. вы продолжаете вводить в него новую информацию снова и снова. Это и есть comet. Вы не выполняете циклические запросы get вечно, вы обрабатываете данные, которые передаются потоком с сервера по мере их поступления, 1 запрос get будет выполняться до истечения времени ожидания, затем в завершенной функции выдается другой запрос get.
-
Опять же, ответ по-прежнему доступен, вы только пишете в нем, не закрывая его каждый раз.
-
Одним из способов было бы установить временную метку для всех уведомлений и загрузить страницу с данными за определенное время, затем ваш первоначальный запрос get предоставляет временную метку, и вы обновляетесь.
-
Я снова предполагаю, что вы удерживаете его до истечения времени ожидания.
Итак, чтобы лучше объяснить, что здесь происходит,
- Ваша страница загружена и отправляет запрос get.
- Запрос / ответ сохраняется в карте.
- Затем каждое обновление отправляется в ОДНОЙ И той же паре запрос / ответ.
- Ваш запрос get прослушивает readystate === 3 (полученные данные) и считывает данные, получая все новое, что было отправлено.
- Когда у них истекает время ожидания / отправлено определенное количество данных / что бы они ни удаляли.
Комментарии:
1. Спасибо! Я взглянул на API для асинхронной функциональности, и, похоже, он действительно работает таким образом. Я запутался, потому что Википедия говорит следующее: «… Браузер выполняет асинхронный запрос к серверу, который может ожидать, пока данные будут доступны, прежде чем ответить… В конце обработки ответа браузер создает и отправляет еще один XHR для ожидания следующего события… Таким образом, браузер всегда сохраняет запрос на сервере незавершенным, на который следует отвечать при возникновении каждого события.» Множество других материалов в сети также определяют такой длительный опрос.
2. @Kevin, это действительно то, что представляет собой длительный опрос, хотя то, что вы описываете в своем вопросе, — это другой стиль comet, называемый потоковым, не длинным опросом. Я думаю, что именно отсюда проистекала ваша путаница.
3. Ах … по какой-то причине я думал, что реализация servlet 3.0 была только с длительным опросом. Похоже, что он реализует потоковую передачу по умолчанию, и фиксация ответа (через вызов complete()) для реализации длительного опроса необязательна.