一个HTTP服务器能否检测到客户端已取消他们的请求?

35

我的Web应用程序必须处理并提供大量数据以显示某些页面。有时,当服务器仍在忙于处理页面时,用户关闭或刷新了页面。 这意味着服务器将继续处理数据数分钟,然后将其发送给不再监听的客户端。

是否可能检测到连接已中断并对其进行响应?

在这个特定的项目中,我们使用Django和NginX或Apache。 我认为这是可能的,因为Django开发服务器似乎会通过打印“Broken Pipe”异常来对取消请求做出反应。我希望它能够引发一个异常,让我的应用程序代码可以捕获。 JSP似乎可以做到这一点node.js也可以在这里

或者,我可以在相关页面注册一个unload事件处理程序,让它执行同步XHR请求,请求取消此用户的先前请求,并进行某种形式的进程间通信以实现此目的。也许,如果较慢的数据处理被移交给另一个我可以更容易地识别和停止的进程,而不会杀死响应进程......

2个回答

24

虽然@Oded的说法是正确的,即HTTP在请求之间是无状态的,但应用服务器确实可以检测到正在处理的请求的基础TCP/IP连接何时已经断开。为什么会这样呢?因为TCP是一种可靠连接的有状态协议。

.Net Web应用程序处理资源密集型请求的常见技术是在开始处理资源密集型工作之前检查Response.IsClientConnected(文档)。没有必要浪费CPU周期将昂贵的响应发送到不再存在的客户端。

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();
    }
}
请回复您的目标应用服务器堆栈,这样我可以提供更相关的示例。
关于您第二个选择使用XHR将客户端页面卸载事件发送到服务器的方法,@Oded的评论指出HTTP在请求之间是无状态的,这是正确的。 这种方法很可能不会成功,特别是在具有多个服务器的农场中。

-3

HTTP是无状态的,因此检测断开连接的唯一方法是通过超时。

请参阅this SO问题的答案(Java Servlet:如何检测浏览器关闭?)。


1
这似乎很奇怪,因为TCP应该能够做到这一点。我猜在抽象层面上有些东西丢失了。 - Nick Retallack
@Nick Retallack - TCP可以做到这一点,但HTTP协议被定义为无状态。这意味着TCP将确保请求或响应可靠地传输,但仅限于此。 - Oded
1
@Oded 是的,但是有没有可能看到TCP连接是否仍在维持? - Earlz
@Earlz - HTTP请求/响应结束后会关闭TCP连接,对吧? - Oded
3
这并不是一个令人满意的答案。显然是可以做到的。唯一的困难在于大多数服务器不会轻易地公开此信息。但是它们确实知道。它们必须知道,否则就无法运行。获取它的一种方法是记录断开连接并让您的应用程序定期检查日志。 - Nick Retallack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接