Automatically reconnecting of SSE clients

One of the standard features of SSE, which works out of the box, is automatic reconnection. SSE clients always try reconnecting to the same stream of events when a connection is unexpectedly lost. If the server includes the ID attribute in events, then the client will automatically include the last known ID into the new connection. The client adds it to a new request as a value of the LAST_EVENT_ID HTTP header. This may be used to start sending new events to the client from this ID, or replay all past events that happened since an event with this ID was sent.

Special care has to be taken if we can't handle reconnection on the server. Ignoring the LAST_EVENT_ID header may lead to multiple invocations of our service in case of a failure. In case the service is supposed to send a sequence of requested results, such as our Forecast service, a connection failure and subsequent reconnection would cause all the results to be sent again. If the header is present in the request, we should take it into account and only send the events that haven't been received by the client. If that's not possible  for example, if the order of events isn't always the same, we should ignore all requests that contain the header because they come from a reconnect. This would disable the reconnect feature and a call to the service would fail and disconnect immediately after a failure message is received from the server without any chance to recover automatically.

The synchronous version of the Forecast service can easily support auto-reconnect. It executes external services in the same order, one after the other, and the order of results is always the same. Therefore, we can skip all the results that were already sent.

Any asynchronous version of the Forecast service that calls external services in parallel produces events in an unpredictable and non-deterministic order. It's then very hard to find out which events were sent based just on the ID of the last request. To avoid calling the same service repeatedly upon connection failure, we ignore all reconnection requests by requiring that the LAST_EVENT_ID header is empty, as follows:

public void getLocationsWithTemperature(
@Null @HeaderParam(HttpHeaders.LAST_EVENT_ID_HEADER) Integer lastEventId, …)

Even if we won't use the value of LAST_EVENT_ID in the method, declaring it as a header with @HeaderParam and placing the @Null validation constraint allows us to execute the method only if the header is empty. If a connection is dropped during receiving events, clients that attempt to reconnect would receive an error status and would stop reconnecting further.

In order to support reconnecting asynchronous calls correctly, the event ID would have to encode all events already sent, to avoid sending them again. However, this can get too complicated and the event ID would grow with the number of events sent. Therefore, it's simpler and safer to raise an error and make the client handle the problem, for example, by restarting the connection from the beginning.

SSE is often used to send an infinite stream of events to which clients can connect at any time. This is where auto-reconnect makes the most sense and helps a lot. Receivers would just reconnect and continue receiving future events as they are produced. This pattern would fit a scenario where the Temperature service should send the current temperature at a regular interval.
For building SSE endpoints that produce an infinite stream of events, JAX-RS provides SseBroadcaster, which you can use to distribute events from a single source of data to every connected SSE client.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.7.102