我正在尝试将长轮询与 JAX-RS (泽西实现)一起使用,但它无法按我的预期工作。也许我误解了什么。我将不胜感激任何建议。
请注意,出于安全原因,不可以选择使用反向连接(例如 Atmosphere、Comet 等)。并不是说我目前正在使用 Tomcat 7 进行开发。
以下方法是从 JQuery Ajax 调用中调用的(使用$.ajax
).
@Path("/poll")
@GET
public void poll(@Suspended final AsyncResponse asyncResponse)
throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
this.asyncResponse = asyncResponse;
// wait max. 30 seconds using a CountDownLatch
latch.await(getTimeout(), TimeUnit.SECONDS);
}
}).start();
}
从我的应用程序调用另一个方法(在 JMS 调用之后):
@POST
@Path("/printed")
public Response printCallback() {
// ...
// I expect the /poll call to be ended here from the client perspective but that is not the case
asyncResponse.resume("UPDATE");
latch.countDown();
return Response.ok().build();
}
如果我删除中的线程创建poll
方法。然后就可以了,但问题是线程正忙。如果我使用线程创建,则该方法将直接返回,并且浏览器不会检测到长轮询的结束。
我究竟做错了什么?
我找到了我的问题的解决方案。问题出在配置上。我们必须指定 Jersey servlet 支持async
然后就可以正常工作了:
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<async-supported>true</async-supported>
...
</servlet>
请注意,如果您有 Servlet 过滤器,它们也需要async-supported
to true.
这也不是创建线程所必需的。泽西岛为我做到了:
@Path("/poll")
@GET
public void poll(@Suspended final AsyncResponse asyncResponse)
throws InterruptedException {
asyncResponse.setTimeout(30, TimeUnit.SECONDS);
this.asyncResponse = asyncResponse;
}
@POST
@Path("/printed")
public Response printCallback(String barcode) throws IOException {
// ...
this.asyncResponse.resume("MESSAGE");
return Response.ok().build();
}
打电话时poll
浏览器等待直到接收MESSAGE
或者如果超时已过,则会收到 HTTP 状态 503。在服务器中,请求线程不会被阻塞,直到超时,而是直接释放。在客户端,我有一个 JavaScript,如果发生超时,它会再次调用该方法,否则我会在页面中处理某些内容。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)