用于长时间运行流程的 Spring SSE

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

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

我们无法实现 WebSocket,因为 ws 协议(protocol)被代理阻止了。我们想在服务器端实现 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;
    }

在客户端我们使用事件源

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

最佳答案

连接保持事件不起作用,因为连接上没有事件。

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

现在通过每 30 秒在连接上发送一些虚假数据并保持连接事件来解决此问题。

关于用于长时间运行流程的 Spring SSE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49505850/

相关文章:

spring-boot - 文件中的 Spring Boot http 安全 jwt key

java - 我 thymeleaf 如何使用页面参数作为属性键?

java - 配置 Spring Boot Test 以使用单独的 bean 集

spring - 将 Spring Bean 绑定(bind)到 Grails 中的服务?

Java spring thymeleaf 显示图片

javascript - 如何清空 Angular 4 中的可观察对象

angular - 让 SystemJS 使用 angular2 包?

java - 如何将数据从 HTML 传输到 Spring Controller

javascript - 使用内置过滤器时,Angular 2 ag-grid 的“清除过滤器”按钮会清除文本框而不刷新列

spring-boot - 如何在spring boot应用程序中将请求数据和响应数据存储到数据库中