我有一个 JAX-RS SSE 端点:
@Path("/")
@ApplicationScoped
public class RestRepo {
@Context
private Sse sse;
// Would it be possible to share an EventSink from different clients (threads)
// instead of re-creating on each request?
@Context SseEventSink eventSink;
@GET
@Path("/sse")
@Produces(MediaType.SERVER_SENT_EVENTS)
public void sendData(final @Context SseEventSink eventSink) {
try (SseEventSink sink = eventSink) {
...
}
// eventSink will be closed automatically
// because of "try-with-resources Statement",
// should I remove the "try-with-resources Statement" to leave it open?
}
}
一切正常。然而,保持
eventSink
打开而不是在每个请求时关闭它是否有意义,例如通过
a) 删除
try (SseEventSink sink = eventSink)
部分或
b) 使用可共享的类实例(不同线程)?
事实上,每次客户端调用时都会创建一个新的
EventSink
实例,我怀疑这是一件好事,因为重新创建这样的权重类别可能没有多大意义。这里的最佳实践是什么?
事实上,最干净的方法是使用“try-with-resources”语句并在每次请求后关闭
SseEventSink
。
SseEventSink
不得在池内共享,因为它应该always 绑定到一个请求。 SseEventSink
不像 WebSocket
那样很重。
也许在未来
SseEventSink
可以通过Java虚拟线程在内部实现(就像所有其他内部REST东西一样,例如GET / POST-Request / Response) - 对于这种“每个请求一个线程”来说,这将是完美的案例。
所以上面的代码被认为是正确的方法。
总而言之:不要在不同的请求之间共享
SseEventSink
,并在发送响应后将其关闭。