Jetty 如何检测 HTTP 连接是否被客户端关闭
Jetty how to detect if HTTP connection was closed by client
问题
基于 Jetty 9 的服务器正在处理耗时(30-60 秒)和计算量大(约 20 个线程参与并行处理)的请求。
由于交互性,客户端可能会在几秒后取消 HTTP 请求并发送一个新请求。
如果客户端关闭连接,最好立即取消计算。
尝试失败
在关闭 HTTP 连接的情况下,尝试写入响应输出流将触发 IOException
。但是,对于此应用程序,HTTP 状态取决于整个计算的结果,因此不可能在处理过程中将任何内容写回套接字。因此,此选项不适用。
Jetty 有方便的 HttpConnection.getCurrentConnection()
方法,可用于获取对与 HTTP 连接相关的某些内部 类 的引用,包括底层 SocketChannel
。虽然我还没有找到一种方法来检查连接的活跃度,但 SocketChannel
或其他 Jetty 的 类 与连接相关。
最好的选择是使用 javax.servlet.AsyncContext
及其 javax.servlet.AsyncListener
。
首先调用 java.servlet.HttpServletRequest.startAsync()
以获取 AsyncContext
。
然后添加您自己的自定义 AsyncListener
,不要忘记在您的 AsyncContext
上也设置超时(因为它的存在会覆盖默认的空闲超时机制)
您将获得对您有用的事件...
- onComplete - 处理完成
- onError - 处理失败(例如连接意外终止)
- onTimeout - AsyncContext 超时已触发
这是 Servlet API 为您的具体情况提供的机制:活动请求期间的计算或后端繁重处理可能会提前终止。
问题
基于 Jetty 9 的服务器正在处理耗时(30-60 秒)和计算量大(约 20 个线程参与并行处理)的请求。
由于交互性,客户端可能会在几秒后取消 HTTP 请求并发送一个新请求。
如果客户端关闭连接,最好立即取消计算。
尝试失败
在关闭 HTTP 连接的情况下,尝试写入响应输出流将触发
IOException
。但是,对于此应用程序,HTTP 状态取决于整个计算的结果,因此不可能在处理过程中将任何内容写回套接字。因此,此选项不适用。Jetty 有方便的
HttpConnection.getCurrentConnection()
方法,可用于获取对与 HTTP 连接相关的某些内部 类 的引用,包括底层SocketChannel
。虽然我还没有找到一种方法来检查连接的活跃度,但SocketChannel
或其他 Jetty 的 类 与连接相关。
最好的选择是使用 javax.servlet.AsyncContext
及其 javax.servlet.AsyncListener
。
首先调用 java.servlet.HttpServletRequest.startAsync()
以获取 AsyncContext
。
然后添加您自己的自定义 AsyncListener
,不要忘记在您的 AsyncContext
上也设置超时(因为它的存在会覆盖默认的空闲超时机制)
您将获得对您有用的事件...
- onComplete - 处理完成
- onError - 处理失败(例如连接意外终止)
- onTimeout - AsyncContext 超时已触发
这是 Servlet API 为您的具体情况提供的机制:活动请求期间的计算或后端繁重处理可能会提前终止。