Java spring SseEmitter / ResponseBodyEmitter: browser reload detection

I am using Server Events (SSE) in Java Spring. When a new client subscribes to the event service, I execute the following code on the REST controller:

SseEmitter emitter = new SseEmitter(-1L); emitter.onCompletion(() -> { logger.debug(TAG + "Emitter completed."); emitters.remove(emitter); }); return emitter; 

Then, when the event should be notified to the clients that I execute:

  for (ResponseBodyEmitter emitter: emitters) { emitter.send("Message #1"); } 

The problem is that when one of the clients restarts the browser, the emitter does not exit (as I expected), and when the above code is called, I get an exception in the intermittent channel. Only after this exception is raised does I see that the emitter is complete.

Is there any way to solve this problem?

+5
source share
1 answer

When the browser restarts, it will install a new EventSource on your server, right? Your problem is with an old one that no longer has a client endpoint.

I suggest you try to find out that this is the same connection with the client, and then explicitly call it completed for the old emitter.

In my case, I can detect this based on the token that EventSource passes as a URL parameter. When I connect the newly created emitter to the "user object", I must complete the previous emitter before assigning a new user field variable.

From your code, it looks like you have a list or set of emitters. Can you possibly create a card instead of it, where you have the customer ID as the key and the emitter as the value?

I can’t say exactly what part of the information to use as a client identifier, since it all depends on your application. In my case, this is a JWT token, but you could just create a client numbering scheme ...

+3
source

Source: https://habr.com/ru/post/1239493/


All Articles