无法通过resteasy获得异步响应

时间:2013-08-29 08:43:04

标签: java rest asynchronous comet resteasy

尽管网上有很多研究,但我无法找到解决问题的方法。 我想从GUI调用一个服务。该服务(Rest方法)使用线程启动异步处理。我希望服务立即给出对GUI的响应,以便不阻止GUI。在线程结束时,服务应该给出第二个响应,指示GUI已完成处理。

我想做的事情似乎与Reasteasy的异步HTTP部分相对应。所以,我已经尝试过这段代码(我只考虑了我的问题的重要部分):

@PUT
@Path("/duplicate/1")
public void duplicate(  UcModel uc,
                                final @Suspend(TIMEOUT_ASYNCHRONOUS_DUPLICATION) AsynchronousResponse response) throws BusinessException {


        Thread t = new Thread() {
            @Override
            public void run() {

                try {
                    Thread.sleep(40000);
                } catch (InterruptedException e) {
                }

                Response jaxrs = Response.ok(result).build();
                response.setResponse(jaxrs);
            }
        };
        t.start();
    }
}

在我的web.xml中,我已经放了这段代码:

<servlet>
    <servlet-name>resteasy-servlet</servlet-name>
    <servlet-class>
        org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher
    </servlet-class>
    <async-supported>true</async-supported>
</servlet>

问题是:Web服务不会立即给出响应。它仅在线程结束时给出响应,并且GUI被阻止。 通过查看代码,我甚至不理解服务如何立即给出“无效”结果的响应。

有关信息:Web服务的调用是在一个Javascript框架ExtJS中进行的。它执行Ajax请求。

如果有人可以帮我解决这个问题,那将会很棒。提前致谢

塞德里克

1 个答案:

答案 0 :(得分:5)

您应该使用两个不同的Web服务来解决此问题。

AsynchronousResponse主要用于帮助服务器线程池性能,而不是用于客户端。

服务器在线程池中具有有限数量的线程,可以满足客户端的请求,并且在AsynchronousResponse的帮助下,您可以将耗时的作业放在后台线程中。

客户端必须等待异步进程完成或超时。只有在那之后才会提交响应,因此对于客户端来说,完成请求几乎需要相同的时间。

其他选择是尝试ChunkedOutput可以找到here的java类。

这是用于以“键入的”块发送消息。适用于长时间运行的流程,需要产生部分响应。

一个例子:

@Path("/test")
public class TestResource {
    @GET
    public ChunkedOutput getTestResponse() {
        final ChunkedOutput chunkedOutputs = new ChunkedOutput(String.class); 
        new Thread() {
            public void run() {
                try {                   
                    while (hasNextValue()) {                         
                         chunkedOutputs.write(getNextLongRunningOperationValue());
                    }                    
                } catch (IOException e) {
                    (...)
                } finally {
                    chunkedOutputs.close();                        
                }
            }
        }.start(); 
        //the chunkedOutputs will be probably returned even before a first value is written by the new thread
        return chunkedOutputs;
    }   

    private boolean hasNextValue() {
        (...)
    }

    private String getNextLongRunningOperationValue() {
        (...) //this takes a lot of time, so it's time for a coffee :)        
    }
}