Как узнать, было ли HTTP-соединение закрыто клиентом? - PullRequest
3 голосов
/ 15 февраля 2020

Проблема

Сервер на базе Jetty 9 требует много времени (30-60 сек c) и вычислительных (~ 20 потоков, участвующих в параллельной обработке) запросов.

Из-за интерактивного характера клиент может отменить HTTP-запрос через несколько секунд и отправить новый.

Желательно немедленно отменить вычисления, если соединение было закрыто клиентом.

Неудачные попытки

  1. При закрытом HTTP-соединении попытка записи в выходной поток ответа вызовет IOException. Хотя, в случае этого приложения, статус HTTP зависит от результата всего вычисления, поэтому невозможно что-либо записать обратно в сокет в середине обработки. Таким образом, эта опция не применима.

  2. У Jetty есть удобный метод HttpConnection.getCurrentConnection(), который можно использовать для получения ссылок на некоторые внутренние классы, связанные с HTTP-соединением, включая базовый SocketChannel. Хотя я не нашел способа проверить живость соединения, хотя SocketChannel или другие классы Jetty, связанные с соединением.

1 Ответ

2 голосов
/ 16 февраля 2020

Лучший выбор - использовать javax.servlet.AsyncContext и javax.servlet.AsyncListener.

. Начните с вызова java.servlet.HttpServletRequest.startAsync(), чтобы получить AsyncContext.

. Затем добавьте пользовательский AsyncListener самостоятельно, не забудьте также установить тайм-аут на AsyncContext (поскольку его существование переопределяет механизм тайм-аута по умолчанию)

Вы получите события, которые что-то значат для вас. ..

  • onComplete - обработка завершена
  • onError - обработка завершилась неудачно (например, неожиданное завершение соединения)
  • onTimeout - тайм-аут AsyncContext сработал

Это механизм, который API сервлетов предоставил именно для вашей ситуации: вычисления или тяжелая обработка бэкэнда во время активной запрос, который может быть прекращен досрочно.

...