弹簧SSE用于长时间运行过程

时间:2018-03-27 06:34:37

标签: spring angular spring-boot websocket server-sent-events

我有一个使用Spring开发的REST API,由Angular 5前端使用。我的服务大约需要5分钟才能完成,我的负载均衡器会断开来自浏览器的连接。

我们无法实现WebSocket,因为代理会阻止ws协议。我们希望在服务器端实现Spring SSE,在angular上实现EventSource作为客户端。

我们有以下客户端和服务器代码。

当异步处理完成并且服务器尝试发送响应时,我们将收到以下错误。我无法理解Tomcat是否正在捕捉连接或浏览器?

17:32:40.101 [GithubLookup-1] INFO  o.a.coyote.http11.Http11Processor - An error occurred in processing while on a non-container thread. The connection will be closed immediately
java.io.IOException: An established connection was aborted by the software in your host machine
    at sun.nio.ch.SocketDispatcher.write0(Native Method)
    at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51)
    at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)

代码

public SseEmitter doSomething() {
      final SseEmitter emitter = new SseEmitter(600000L);
      CompletableFuture<Response> res = ... some Service call which takes 5 min, but annotated with @Async
      completableFuture.whenComplete((res, ex) -> {
        emitter.send(res);
        emitter.complete();
      }
      emitter.send("Running"); // Some fake status to let client know it is accepted and running
      return emitter;
    }

在客户端,我们使用eventsource

  let eventSource = new EventSource(url, {
      xhrHeaders: {
          'Content-Type': 'text/event-stream'
      }
  });
  eventSource.onmessage = (event) => {
      console.log('Received event: ', event);
  };

1 个答案:

答案 0 :(得分:1)

连接保持活动状态不起作用,因为连接上没有活动。

我的负载均衡器正在终止连接。

现在通过每隔30秒在连接上发送一些假数据并保持连接活动来解决这个问题。