服务器发送事件与Spring有一个线程被释放请求

时间:2018-02-12 10:43:35

标签: java spring server-sent-events

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

我在这里有一个例子,但实际上我并不知道如何让这个线程资源示例足够清楚。

我不想在这里使用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);
  }
}

1 个答案:

答案 0 :(得分:1)

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

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

有时候我写了post来使用不同的线程发送SSE消息。我希望这会有所帮助。

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