Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Jersey/JAX-RS 2 AsyncResponse-如何跟踪当前的长轮询调用者_Java_Web Services_Jersey_Jax Rs_Jersey 2.0 - Fatal编程技术网

Java Jersey/JAX-RS 2 AsyncResponse-如何跟踪当前的长轮询调用者

Java Jersey/JAX-RS 2 AsyncResponse-如何跟踪当前的长轮询调用者,java,web-services,jersey,jax-rs,jersey-2.0,Java,Web Services,Jersey,Jax Rs,Jersey 2.0,我的目标是支持多个web服务调用方的长轮询,并跟踪长轮询(即已连接)中当前“停靠”的调用方。所谓“长轮询”,我的意思是调用方调用web服务,而服务器(web服务)不会立即返回,而是让调用方等待一段预设的时间(在我的应用程序中为一小时),或者如果服务器有消息要发送给调用方,则会提前返回(在这种情况下,服务器通过调用asyncResponse.resume(“消息”)返回消息) 我将把这个问题分成两个问题 第一个问题:这是一个合理的方式“停车”的来电谁是长期投票 @GET @生成(MediaType

我的目标是支持多个web服务调用方的长轮询,并跟踪长轮询(即已连接)中当前“停靠”的调用方。所谓“长轮询”,我的意思是调用方调用web服务,而服务器(web服务)不会立即返回,而是让调用方等待一段预设的时间(在我的应用程序中为一小时),或者如果服务器有消息要发送给调用方,则会提前返回(在这种情况下,服务器通过调用asyncResponse.resume(“消息”)返回消息)

我将把这个问题分成两个问题

第一个问题:这是一个合理的方式“停车”的来电谁是长期投票

@GET
@生成(MediaType.TEXT\u PLAIN)
@ManagedAsync
@路径(“/poll/{id}”)
公共响应轮询器(@Suspended final AsyncResponse,@PathParam(“id”)字符串callerId){
//将此异步响应添加到HashMap,该HashMap由Jersey跨web服务调用持久化。
//可能有消息要发送给调用者的其他应用程序组件将查找
//在此HashMap中由callerId调用,并在其异步响应上调用resume()。
callerIdAsyncResponseHashMap.put(callerId,asyncResponse);
asyncResponse.setTimeout(3600,TimeUnit.SECONDS);
asyncResponse.setTimeoutHandler(新的TimeoutHandler(){
@凌驾
公共void handleTimeout(异步响应异步响应){
resume(Response.ok(“TIMEOUT”).build());
}
});
返回Response.ok(“COMPLETE”).build();
}
这很好。我只是不确定它是否遵循最佳实践。在方法末尾有“return Response…”行似乎很奇怪。这行在调用方首次连接时执行,但据我所知,“COMPLETE”结果从未实际返回给调用方。调用方要么得到“TIMEOUT”当服务器需要通知调用方事件时,服务器通过asyncResponse.resume()发送的响应或其他响应消息

第二个问题:我目前面临的挑战是在HashMap中准确反映当前轮询呼叫者的数量。当呼叫者停止轮询时,我需要从HashMap中删除其条目。呼叫者离开的原因有三个:1)3600秒,因此超时,2)另一个应用程序组件在HashMap中查找调用者并调用asyncResponse.resume(“消息”),以及3)HTTP连接因某种原因中断,例如有人关闭运行客户端应用程序的计算机

因此,JAX-RS有两个回调,我可以注册以收到连接结束的通知:CompletionCallback(出于上面的结束轮询原因#1和#2)和ConnectionCallback(出于上面的结束轮询原因#3)

我可以像这样将这些添加到我的web服务方法中:

@GET
@生成(MediaType.TEXT\u PLAIN)
@ManagedAsync
@路径(“/poll/{id}”)
公共响应轮询器(@Suspended final AsyncResponse,@PathParam(“id”)字符串callerId){
asyncResponse.register(新的CompletionCallback(){
@凌驾
未完成的公共空间(可丢弃){
//?
}
});
asyncResponse.register(新的ConnectionCallback(){
@凌驾
公共无效onDisconnect(异步响应已断开){
//?
}
});
//将此异步响应添加到HashMap,该HashMap由Jersey跨web服务调用持久化。
//可能有消息要发送给调用者的其他应用程序组件将查找
//在此HashMap中由callerId调用,并在其异步响应上调用resume()。
callerIdAsyncResponseHashMap.put(callerId,asyncResponse);
asyncResponse.setTimeout(3600,TimeUnit.SECONDS);
asyncResponse.setTimeoutHandler(新的TimeoutHandler(){
@凌驾
公共void handleTimeout(异步响应异步响应){
resume(Response.ok(“TIMEOUT”).build());
}
});
返回Response.ok(“COMPLETE”).build();
}
正如我所说,挑战在于使用这两个回调从HashMap中删除不再轮询的调用方。ConnectionCallback实际上是两者中比较容易的一个。因为它接收一个asyncResponse实例作为参数,所以我可以使用它从HashMap中删除相应的条目,如下所示:

asyncResponse.register(新的ConnectionCallback(){
@凌驾
公共无效onDisconnect(异步响应已断开){
迭代器迭代器=callerIdAsyncResponseHashMap.entrySet().Iterator();
while(iterator.hasNext()){
Map.Entry=iterator.next();
if(entry.getValue().equals(断开连接)){
iterator.remove();
打破
}
}
}
});
但是,对于CompletionCallback,由于在触发回调时已经完成或取消了asyncResponse,因此没有传入asyncResponse参数。因此,似乎唯一的解决方案是运行HashMap条目,检查完成/取消的条目并删除它们,如下所示。(注意,我不需要知道调用方离开是因为调用了resume()还是因为它超时,所以我不看“throwable”参数)

asyncResponse.register(新的CompletionCallback(){
@凌驾
未完成的公共空间(可丢弃){
迭代器迭代器=callerIdAsyncResponseHashMap.entrySet().Iterator();
while(iterator.hasNext()){
Map.Entry=iterator.next();
if(entry.getValue().isDone()| | entry.getValue().isCancelled()){
iterator.remove();
}
}
}
});
如有任何反馈,将不胜感激。这种做法合理吗?是否有更好或更好的Jersey/JAX-RS方法来执行此操作?

您的poller()方法不需要返回响应即可参与异步处理。它可以恢复