对于异步编程,Jersey (JAX-RS) 提供了ConnectionCallback
当连接断开时要执行的回调。来自泽西岛文档 https://jersey.java.net/documentation/latest/async.html#d0e8863:
由于某些异步请求可能需要很长时间才能处理,因此客户端可能会
决定在响应之前终止与服务器的连接
已恢复或在完全写入客户端之前。到
可以使用 ConnectionCallback 处理这些用例。这
仅当连接过早时才会执行回调
在将响应写入后面时终止或丢失
客户。请注意,当有响应时,不会调用此回调
写入成功并且客户端连接按预期关闭。
听起来不错,但我永远无法让它点火。
这是一些代码:
@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 中查看以下代码:
https://github.com/jersey/jersey/blob/a6ff4d50da13d45ad90fd7375a15a31afa02e489/core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java#L723 https://github.com/jersey/jersey/blob/a6ff4d50da13d45ad90fd7375a15a31afa02e489/core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java#L723
https://github.com/jersey/jersey/blob/b7907e279010e7035a7a3e529993d22f77a21e08/core-server/src/main/java/org/glassfish/jersey/server/ChunkedOutput.java#L246-L252 https://github.com/jersey/jersey/blob/b7907e279010e7035a7a3e529993d22f77a21e08/core-server/src/main/java/org/glassfish/jersey/server/ChunkedOutput.java#L246-L252
如果在写入响应时出现 IOException,则会抛出这些异常。因此,为了回答您的问题,没有轮询或类似的机制来不断检查客户端是否已连接,而是断开连接时仅当出现 IOException 时才调用该方法,该异常通常在写入响应时发生。
更新1:
我还想引用你自己的问题:
“仅当连接过早时才会执行此回调
在将响应写入后面时终止或丢失
客户”
So, 除非你尝试写入该流,你的回调永远不会被触发。需要明确的是,它并不是在没有响应写入或响应为 202 时调用,而是在连接提前终止时调用。正在写入响应时.
恐怕这个问题没有解决方法,除非您编写一些带有某种轮询的低级网络编程。但我不建议你这么做。
我建议您重新考虑处理此失败的方式。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)