Search code examples
javaspringserver-sent-events

Server Sent Event with Spring with having a thread being freed from request


I need to show off an example of server sent events. I learned about it in a spring talk. People used Webflux there to show the reactive principles. I understood the part on how this will free thread resources because the request thread won't be blocked until the job is done and the server returns the response.

I have an example here but actually I don't really know how I can make this thread resource example be clear enough.

I do not want to use the WebFlux framework here. Just need to know what to put into a separate thread here - if necessary at all?!

As you can see I have a GetMapping to subscribe to the event stream. And then I have a GetMapping to launch or fire an event. This example is fast for sure but should be considered as heavy database call.

So I actually need to have the whole logic be separated in another thread right? So the request thread is free as soon as possible?

@RestController
public class EventStreamRequestHandler {

  @Autowired
  ObjectMapper objectMapper;
  SseEmitter sseEmitter = new SseEmitter(1000000L);

  @GetMapping("/get/event/stream")
  public SseEmitter getStream() {
    return this.sseEmitter;
  }


  @GetMapping("/launch/event")
  public void fireEvent() throws IOException {
    Person peter = new Person("Peter", "25");
    String valueAsString = objectMapper.writeValueAsString(peter);

    SseEmitter.SseEventBuilder sseEventBuilder = SseEmitter.event()
            .id("foo") 
            .name("awesome-event") 
            .data(valueAsString); 

    sseEmitter.send(sseEventBuilder);
  }
}

Solution

  • Yes, Server sent events are supposed to send messages to the client asynchronously without client keep on polling for message.

    The sending of messages from client to server needs to be done asynchronously. With the way you have done it. When a GET request is sent to /get/event/stream an SseEmitter will be created but messages will only be sent when a GET request is sent to /launch/event. And the GET request thread for /launch/event will be used to send the message.

    Sometime back I wrote post to send SSE messages using a different thread. I hope this helps.

    But I don't recommend storing the SseEmitter in an instance variable as it will overridden by multiple requests. You must at least make it ThreadLocal