我需要展示服务器发送事件的示例。我在春天的谈话中了解到了这一点。人们在那里使用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);
}
}
答案 0 :(得分:1)
是的,服务器发送的事件应该异步地向客户端发送消息,而客户端不继续轮询消息。
从客户端到服务器的消息发送需要异步完成。用你的方式完成它。当GET请求发送到/get/event/stream
时,将创建一个SseEmitter,但只有在向/launch/event
发送GET请求时才会发送消息。并且/launch/event
的GET请求线程将用于发送消息。
有时候我写了post来使用不同的线程发送SSE消息。我希望这会有所帮助。
但我不建议将SseEmitter
存储在实例变量中,因为它会被多个请求覆盖。你必须至少使它成为ThreadLocal