对于异步编程,Jersey (JAX-RS) 提供了一个 ConnectionCallback 回调,在连接断开时执行。来自Jersey docs :
As some async requests may take long time to process the client may decide to terminate its connection to the server before the response has been resumed or before it has been fully written to the client. To deal with these use cases a ConnectionCallback can be used. This callback will be executed only if the connection was prematurely terminated or lost while the response is being written to the back client. Note that this callback will not be invoked when a response is written successfully and the client connection is closed as expected.
听起来不错,但我永远无法启动它。
这是一些代码:
@GET
@Produces(MediaType.TEXT_PLAIN)
@ManagedAsync
@Path("/poll")
public void poll(@Suspended final AsyncResponse asyncResponse) {
asyncResponse.register(new CompletionCallback() {
@Override
public void onComplete(Throwable throwable) {
logger.info("onComplete called.");
}
});
asyncResponse.register(new ConnectionCallback() {
@Override
public void onDisconnect(AsyncResponse disconnected) {
logger.info("onDisconnect called.");
}
});
asyncResponse.setTimeout(POLL_TIMEOUT_SECONDS, TimeUnit.SECONDS);
asyncResponse.setTimeoutHandler(new TimeoutHandler() {
@Override
public void handleTimeout(AsyncResponse asyncResponse) {
logger.info("handleTimeout called.");
asyncResponse.resume(Response.status(Response.Status.OK).entity("TIMEOUT").build());
}
});
}
显示的另外两个回调,CompletionCallback 和 TimeoutHandler,触发得很好,没有失败。如果达到指定的超时持续时间,TimeoutHandler 将触发。如果恢复 AsyncResponse 实例,CompletionCallback 将触发。
但是,使用 ConnectionCallback,我可以关闭、终止或以其他方式停止连接到上面所示的 Web 服务的客户端,而 ConnectionCallback 永远不会被触发。
我错过了什么吗? ConnectionCallback 是否在 Jersey 中实现? (它在 JAX-RS 规范中是可选的,但 Jersey 文档在谈论它时就好像它已经实现了一样。)
如有任何意见,我们将不胜感激。
最佳答案
ConnectionCallback 确实在 Jersey 实现了。并且还会调用“onDisconnect”回调。您可以在 Jersey 中查看以下代码:
这些是在写入响应时抛出 IOException 的情况。因此,为了回答您的问题,没有轮询或类似的机制来不断检查客户端是否已连接,而是仅在出现通常在写入响应时发生的 IOException 时才调用 onDisconnect 方法。
更新 1:
另外我想引用你自己的问题:
"This callback will be executed only if the connection was prematurely terminated or lost while the response is being written to the back client"
因此,除非您尝试写入该流,否则您的回调将永远不会被触发。需要明确的是,它并不是要在没有写入响应或响应为 202 时调用,而是要在正在写入响应时连接过早终止时调用。
恐怕这个问题没有解决方法,除非你编写一些带有某种轮询的低级网络程序。但我不建议您这样做。
我建议您重新考虑处理此故障的方式。
关于java - AsyncResponse ConnectionCallback 不会在 Jersey 中触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26794176/