Unicast message over SSE in Spring Boot MVC

826 views Asked by At

I have a uses case in which I need to send push notifications to the Android or IOS client. The notification event should be unicast. Each message is relevant for a single client only.

How can I achieve that? I have previously broadcast events to multiple clients using code like below. I want to send a notification to an event particular subscriber for which event belongs over SSE.


@GetMapping("/sse-emitter")
public SseEmitter sseEmitter() {
   SseEmitter emitter = new SseEmitter();
   Executors.newSingleThreadExecutor().execute(() -> {
       try {
           for (int i = 0; true; i++) {
               SseEmitter.SseEventBuilder event = SseEmitter.event()
                       .id(String.valueOf(i))
                       .name("SSE_EMITTER_EVENT")
                       .data("SSE EMITTER - " + LocalTime.now().toString());
               emitter.send(event);
               Thread.sleep(1000);
           }
       } catch (Exception ex) {
           emitter.completeWithError(ex);
       }
   });
   return emitter;
}

P.S I am using this approach to keep map of SSEEmitters.

SSE Emitter : Manage timeouts and complete()

I will test it properly and update here

1

There are 1 answers

0
Vladyslav Nikolaiev On

You could leverage Spring compatible SSE event bus lib to have your clients mapped to a unique id. So that you could later distinguish them.

A part of the nice article @Pankaj Chimbalkar left in comments

... The library creates a bean of type SseEventBus that an application can inject into any Spring-managed bean.

@Controller
public class SseController {
  private final SseEventBus eventBus;
  public SseController(SseEventBus eventBus) {
    this.eventBus = eventBus;
  }

  @GetMapping("/register/{id}")
  public SseEmitter register(@PathVariable("id") String id) {
    return this.eventBus.createSseEmitter(id, SseEvent.DEFAULT_EVENT)
  }
}

The library expects each client sends a unique id. An application can create such an id with a UUID library like https://github.com/uuidjs/uuid. For starting the SSE connection, the client calls the endpoint with the createSseEmitter method and sends the id and optionally the names of the events he is interested in.

const uuid = uuid();
const eventSource = new EventSource(`/register/${uuid}`);
eventSource.addEventListener('message', response => {
    //handle the response from the server
    //response.data contains the data line 
}, false);