Spring 服务器发送事件,线程从请求中释放

Server Sent Event with Spring with having a thread being freed from request

我需要展示一个服务器发送事件的例子。我是在一次 spring 谈话中了解到的。人们在那里使用 Webflux 来展示反应性原则。我了解这将如何释放线程资源的部分,因为在作业完成并且服务器 returns 响应之前,请求线程不会被阻塞。

我这里有一个示例,但实际上我真的不知道如何才能使这个线程资源示例足够清楚。

我不想在这里使用WebFlux 框架。只需要知道在这里将什么放入单独的线程中 - 如果有必要的话?!

如您所见,我有一个 GetMapping 来订阅事件流。然后我有一个 GetMapping 到 launch 或触发一个事件。这个例子肯定很快,但应该被认为是大量的数据库调用。

所以我实际上需要将整个逻辑分离到另一个线程中,对吗?所以请求线程尽快空闲?

@RestController
public class EventStreamRequestHandler {

  @Autowired
  ObjectMapper objectMapper;
  SseEmitter sseEmitter = new SseEmitter(1000000L);

  @GetMapping("/get/event/stream")
  public SseEmitter getStream() {
    return this.sseEmitter;
  }


  @GetMapping("/launch/event")
  public void fireEvent() throws IOException {
    Person peter = new Person("Peter", "25");
    String valueAsString = objectMapper.writeValueAsString(peter);

    SseEmitter.SseEventBuilder sseEventBuilder = SseEmitter.event()
            .id("foo") 
            .name("awesome-event") 
            .data(valueAsString); 

    sseEmitter.send(sseEventBuilder);
  }
}

是的,服务器发送的事件应该异步地向客户端发送消息,而不需要客户端继续轮询消息。

从客户端到服务器的消息发送需要异步完成。用你做的方式。当 GET 请求发送到 /get/event/stream 时,将创建一个 SseEmitter,但只有当 GET 请求发送到 /launch/event 时才会发送消息。 /launch/event 的 GET 请求线程将用于发送消息。

前段时间我写 post 使用不同的线程发送 SSE 消息。希望对您有所帮助。

但我不建议将 SseEmitter 存储在实例变量中,因为它会被多个请求覆盖。你必须至少做到 ThreadLocal