【问题标题】:How does client handles deferred result in long running rest calls客户端如何处理延迟结果导致长时间运行的休息调用
【发布时间】:2016-12-25 17:16:43
【问题描述】:

我正在学习使用 spring mvc/boot 休息。我了解基本的休息电话,但我无法理解长时间运行/非阻塞的休息电话。

我知道,对于长时间运行的休息调用,我们会启动一个单独的线程,服务器会向客户端返回一个 DeferredResult 对象,但是当处理线程完成时如何通知客户端?

有人可以为我提供一个如何在客户端处理此问题的示例吗?

还有非java客户端如何处理这样的请求?

【问题讨论】:

  • 由于您的问题似乎很笼统,因此我给出了一个不受 java 或 spring 约束的理论答案。据我所知,在 REST 中没有服务器端通知之类的东西。相反,有一个客户端轮询活动。我举一个典型的例子:你想创建一个资源,但是服务器不能在线满足你的请求。服务器将返回202 Accepted 状态消息,客户端知道,从现在开始,它可以轮询该资源。
  • 只是为了补充前面的评论:在 REST 中没有“现成的”服务器通知机制,但您可以实现 RESTful 发布-订阅。但是,当然,这是另一回事。

标签: java spring rest nonblocking


【解决方案1】:

我给出的答案与 Spring 相关,与任何非 Java 客户端无关。

有一个 AsyncRestTemplate 可用于从长时间运行的 Rest Webservice 中检索

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/AsyncRestTemplate.html

//方式1

    @Test
    public void testGetClusterAsyncWay1() 
    {
        Future<ResponseEntity<ClusterDTO>> future =  asyncRestTemplate.getForEntity(BASE_URI+"/async/{clusterId}", ClusterDTO.class,1);

        //Do some other work in your method and after that ping the service to retrieve the result

        //Waits for the computation to get complete and then get the result , you can use different version of get which has timeout option
        ResponseEntity<ClusterDTO> response = future.get();

        ClusterDTO cluster = response.getBody();

        System.out.println("testGetClusterAsync()"+cluster.getClusterName());

}

//方式2

    @Test
    public void testGetClusterAsyncWay2() 
    {

          ListenableFuture<ResponseEntity<ClusterDTO>> future = 
                    asyncRestTemplate.getForEntity(BASE_URI+"/async/{clusterId}", ClusterDTO.class,17);

       future.addCallback(new MyCallbackHandler());

        //do stuff
        for(int i=0;i<10000;i++)
        {

            System.out.println(i);
        }

    }
    class MyCallbackHandler implements  ListenableFutureCallback<ResponseEntity<ClusterDTO>>{

    @Override
     public void onSuccess(ResponseEntity<ClusterDTO> response) {
      ClusterDTO cluster = response.getBody();
      System.out.println(cluster);
      System.out.println("Success******************************");
     }

    @Override
    public void onFailure(Throwable ex) {
    System.out.println("onFailure******************************");
    ex.printStackTrace();

    }

}

【讨论】:

  • 处理程序将在任务完成时被调用,但您仍然无法通知客户端这是服务器发送事件发挥作用的地方。
【解决方案2】:

Web 不是为长时间运行的任务而构建的,它纯粹是请求/响应。但是,您可以使用服务器发送事件将通知返回给客户端或使用 Websockets。 Spring 支持两者。

https://github.com/cedricziel/demo-sse-spring-boot

https://spring.io/guides/gs/messaging-stomp-websocket/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    • 1970-01-01
    • 2019-07-06
    • 2010-11-08
    相关资源
    最近更新 更多