Может ли HTTP-сервер обнаружить, что клиент отменил свой запрос?
Мое веб-приложение должно обрабатывать и обслуживать множество данных для отображения определенных страниц. Иногда пользователь закрывает или обновляет страницу, пока сервер все еще занят обработкой. Это означает, что сервер будет продолжать обрабатывать данные в течение нескольких минут, только чтобы отправить их клиенту, который больше не прослушивает.
Можно ли обнаружить, что соединение было повреждено и реагировать на него?
В этом конкретном проекте мы используем Django и NginX или Apache. Я предположил, что это возможно, потому что сервер разработки Django, похоже, реагирует на отмененные запросы, печатав исключения Broken Pipe. Я бы хотел, чтобы это вызвало исключение, которое мог бы заразить мой код приложения. Похоже, JSP может это сделать. Так может node.js здесь.
В качестве альтернативы, я мог бы зарегистрировать обработчик события выгрузки на рассматриваемой странице, если бы он выполнял синхронный XHR, запрашивая, чтобы предыдущий запрос от этого пользователя был отменен, и делайте какую-то межпроцессную связь, чтобы сделать так. Возможно, если медленная обработка данных была передана другому процессу, который я мог бы легче идентифицировать и убить, не убивая процесс ответа...
Ответы
Ответ 1
В то время как @Oded верно, что HTTP является безстоящим между запросами, серверы приложений действительно могут обнаружить, когда базовое соединение TCP/IP нарушилось для обрабатываемого запроса . Почему это? Поскольку протокол TCP является протоколом с проверкой состояния для надежных соединений.
Общей методикой для веб-приложений .NET, обрабатывающих ресурсоемкий запрос, является проверка Response.IsClientConnected
(docs) перед началом ресурсоемкой работы, Нет смысла тратить процессорные циклы на отправку дорогостоящего ответа на клиента, которого больше нет.
private void Page_Load(object sender, EventArgs e)
{
// Check whether the browser remains
// connected to the server.
if (Response.IsClientConnected)
{
// If still connected, do work
DoWork();
}
else
{
// If the browser is not connected
// stop all response processing.
Response.End();
}
}
Пожалуйста, ответьте со своим стеке целевого сервера приложений, чтобы я мог предоставить более подходящий пример.
Что касается 2-й альтернативы использованию XHR для отправки сообщений о выгрузке страницы на сервер, @Oded комментарий о том, что HTTP без апатридов между запросами находится на месте. Это вряд ли сработает, особенно в ферме с несколькими серверами.
Ответ 2
HTTP является безстоящим, поэтому единственный способ обнаружить отключенный клиент - через тайм-ауты.
См. ответы на this Вопрос SO (Java Servlet: как обнаружить закрытие браузера?).