Обнаружение прерванных запросов в HttpServlet - PullRequest
2 голосов
/ 07 декабря 2010

Есть ли способ узнать, отменен ли запрос HttpServletRequest?

Я пишу приложение для мгновенного просмотра браузера (какой-то чат): клиенты запрашивают новые события в цикле, используя AJAX-HTTP.-Запросы.Сервер (Tomcat) обрабатывает запросы в HttpServlet.Если для этого клиента нет новых событий, сервер задерживает ответ до тех пор, пока не прибудет новое событие или не произойдет тайм-аут (30 секунд).

Теперь я хочу определить клиентов, которые больше не опрашивают.Поэтому я запускаю Kick-Timer в конце запроса, который останавливается при поступлении нового запроса.Если клиент закрывает окно браузера, TCP-соединение закрывается и HTTP-запрос прерывается.

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

Было бы замечательно, если бы я мог как-то прослушивать события прерывания соединения и затем уведомлять ожидающий запрос, чтобы остановить его.Но я не смог найти ничего подобного в запросах HttpServletRequest или HttpServletResponse ...

Ответы [ 3 ]

1 голос
/ 20 февраля 2012

Возможно, вы используете какое-то уведомление о потоке (Semaphores или Object.wait) для хранения и освобождения потоков сервлета.Как насчет добавления тайм-аута (~ 10 с) к ожиданию, затем каким-то образом проверить, все ли соединение еще живо, и затем продолжить ожидание еще 10 с, если соединение все еще там.

Я не знаю,Существуют надежные способы опроса «живучести» соединения (например, resp.getOutputStream, не генерирующий исключение) и, если да, то какой из них лучший (самый надежный, наименее интенсивный процессор).

1 голос
/ 13 июля 2018

Это, вероятно, больше не поможет OP, но может помочь другим, пытающимся обнаружить прерванные HTTP-соединения в HttpServlet в целом, так как у меня была похожая проблема, и я наконец нашел ответ.

Ключ заключается в том, что, когда клиент отменяет запрос, обычно единственный способ для сервера выяснить это - отправить некоторые данные обратно клиенту, что в этом случае не удастся. Я хотел определить, когда клиент перестает ждать длинных вычислений на сервере, поэтому я периодически записывал один символ в тело ответа через средство записи HttpServletResponse. Чтобы принудительно отправить данные клиенту, вы должны вызвать HttpServletResponse.flushBuffer(), который выдает ClientAbortException, если соединение прерывается.

0 голосов
/ 07 декабря 2010

Похоже, что ожидающие запросы могут довольно быстро снизить производительность вашей системы. Потоки, отвечающие на запросы, быстро устали бы, если бы запросы оставались открытыми. Вы можете попробовать завершить все запросы (и вернуть «null» вашим клиентам, если сообщения нет) и создать поток на бэкэнде, который отслеживает, сколько времени прошло с момента опроса клиентов. Поток может пометить клиента как неактивного.

...