JAX-RS和长轮询 [英] JAX-RS and Long Polling

查看:138
本文介绍了JAX-RS和长轮询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对JAX-RS(Jersey实现)使用长时间轮询,但它没有按我预期的那样工作.也许我误会了一些东西.我将不胜感激任何建议.

I'm trying to use long polling with JAX-RS (Jersey implementation) and it doesn't work as I expect. Maybe I'm misunderstanding something. I would appreciate any advice.

请注意,出于安全考虑,不可以使用反向连接(例如Atmosphere,Comet等).并不是说我目前正在使用Tomcat 7.

Please note that using a reverse connection (something like Atmosphere, Comet, etc) is not a option for security reason. Not that I'm currently developing with Tomcat 7.

从JQuery Ajax调用(使用$.ajax)调用以下方法.

The following method is invoked from a JQuery Ajax call (using $.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调用之后):

The other method is invoked from my application (after a JMS call):

@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方法中删除线程创建.然后就可以了,但是问题是线程很忙.如果我使用Thread创建,则该方法将直接返回,并且浏览器未检测到长轮询的结束.

If I remove the Thread creation in the poll method. Then it works, but the problem is that a Thread is busy. If I use the Thread creation, then the method is returning directly and the browser is not detecting the end of the long polling.

我在做什么错了?

推荐答案

我找到了解决问题的方法.问题出在配置中.我们必须指定Jersey servlet支持async,然后才能正常工作:

I found the solution of my problem. The problem was in the configuration. We must specify that the Jersey servlet supports async and then it works fine:

<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-supportedtrue.

Please note that if you have Servlet filters, they also need to be async-supported to true.

创建线程也不是必须的.泽西(Jersey)为我做到了:

This was also not necessary to create a thread. Jersey does it for me:

@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,如果发生超时,JavaScript将再次调用该方法,否则我将在页面中进行处理.

When calling poll the browser waits until receiving MESSAGE or receiving a HTTP status 503 if the timeout is elapsed. In the server, the request thread is not blocked until the timeout but released directly. In the client side, I have a JavaScript which is calling the method again if the timeout occurs, otherwise I process something in the page.

这篇关于JAX-RS和长轮询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆