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
我需要展示一个服务器发送事件的例子。我是在一次 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