JAX-RS和长轮询

我正在尝试使用JAX-RS(Jersey实现)进行长轮询,但它不能像我预期的那样工作。 也许我误会了什么。 我很感激任何建议。

请注意,出于安全原因,使用反向连接(类似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 ,然后它可以正常工作:

  Jersey REST Service org.glassfish.jersey.servlet.ServletContainer true ...  

请注意,如果您有Servletfilter,则还需要async-supported 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,如果发生超时,它会再次调用该方法,否则我会在页面中处理某些内容。