I think this question is not a duplicate. The server sent an event from Jersey: EventOutput does not close after the client crashes , but is probably connected to Events with the Jersey server / server - writing to an idle connection does not raise an exception .
In chapter 15.4.2 of the Jersey SseBroadcaster documentation:
However, SseBroadcaster internally identifies and processes client disconnects as well. When the client closes the connection, the broadcaster detects this and removes the outdated connection from the internal collection of registered events, and also frees up all server resources associated with the outdated connection.
I canβt confirm this. In the following test SseBroadcaster , I see that the subclass method of SseBroadcaster onClose() never called: not when closing EventInput , and not when sending another message.
public class NotificationsResourceTest extends JerseyTest { final static Logger log = LoggerFactory.getLogger(NotificationsResourceTest.class); final static CountingSseBroadcaster broadcaster = new CountingSseBroadcaster(); public static class CountingSseBroadcaster extends SseBroadcaster { final AtomicInteger connectionCounter = new AtomicInteger(0); public EventOutput createAndAttachEventOutput() { EventOutput output = new EventOutput(); if (add(output)) { int cons = connectionCounter.incrementAndGet(); log.debug("Active connection count: "+ cons); } return output; } @Override public void onClose(final ChunkedOutput<OutboundEvent> output) { int cons = connectionCounter.decrementAndGet(); log.debug("A connection has been closed. Active connection count: "+ cons); } @Override public void onException(final ChunkedOutput<OutboundEvent> chunkedOutput, final Exception exception) { log.trace("An exception has been detected", exception); } public int getConnectionCount() { return connectionCounter.get(); } } @Path("notifications") public static class NotificationsResource { @GET @Produces(SseFeature.SERVER_SENT_EVENTS) public EventOutput subscribe() { log.debug("New stream subscription"); EventOutput eventOutput = broadcaster.createAndAttachEventOutput(); return eventOutput; } } @Override protected Application configure() { ResourceConfig config = new ResourceConfig(NotificationsResource.class); config.register(SseFeature.class); return config; } @Test public void test() throws Exception {
Maybe JerseyTest not a good way to test this. In a less ... clinical setting that uses the JavaScript EventSource , I see onClose() , which is called, but only after the message is broadcast over a previously closed connection.
What am I doing wrong?
Why does SseBroadcaster not detect a client closing a connection?
Subsequent
I found JERSEY-2833 , which was rejected using Works, as was designed:
According to the Jersey documentation in the SSE chapter ( https://jersey.java.net/documentation/latest/sse.html ) in 15.4.1, he mentioned that Jersey does not explicitly close the connection, it is the responsibility of the resource or client method.
What does it mean? Should a resource force a timeout and kill all active and closed connections?