I am using server sent events between a spring boot application (as the sender) and jersey (as a receiver). This was working fine, until it became time to upgrade the spring boot version. After the spring boot update the problem is as follows:
- The jersey sseClient subscribes to the sseEvent.
- The thread is blocked (even though I can see that on the sending side, a emitter was made and put in the recepients list).
- The thread gets "unstuck" when the timeout of the sseEvent occurs and jersey automatically reconnects and everything is fine.
This is the setup:
Dependencies
Jersey:
dependency 'org.glassfish.jersey.core:jersey-client:2.30.1'
dependency 'org.glassfish.jersey.inject:jersey-hk2:2.30.1'
dependency 'org.glassfish.jersey.media:jersey-media-sse:2.30.1'
and spring boot
dependency 'org.springframework.boot:spring-boot-starter:2.1.4.RELEASE' --> updated to 2.2.4.RELEASE
dependency 'org.springframework.boot:spring-boot-starter-web:2.1.4.RELEASE'--> updated to 2.2.4.RELEASE
The code looks as follows
Receiving end (Jersey):
final Client sseClient = ClientBuilder.newBuilder().build();
final WebTarget target = sseClient.target("some_url");
sseEventSource = EventSource.target(target).build();
sseEventSource.register( // do something );
sseEventSource.open();
Sending end (spring boot):
@GetMapping("/subscribe")
public SseEmitter subscribe() {
SseEmitter emitter = new SseEmitter(60_000L);
// put emitter in recepients list
emitter.onCompletion(() -> {
// do something
});
emitter.onTimeout(() -> {
// do something
});
emitter.onError(// log error);
return emitter;
}
The reason the thread is "stuck" is because of jersey. When you call the sseEventSource.open(), you can see that the Jersey EventSource calls processor.awaitFirstContact(); Which is where everything halts until the timeout (or any event from the sending party).
So my question: Scince I did not change anything on the Jersey side and only updated the spring boot version, what has changed !? Cleary it has something to do with the spring boot side not fulfilling the awaitFirstContact agreement anymore. But can't figure that part out.
There is a workaround The workaround is easy, when u initialize the sseEmitter, you can immediately send a init event and all is good.