Detecting end of Flux data v.s. error

2020-06-21 06:15发布

问题:

Currently looking at SSE using Angular 5 and Spring 5 webflux. The basic application is working correctly, but whilst investigating error handling we've noticed that the EventSource in the angular application doesn't see any difference between spring closing the connection due to reaching the end of the Flux stream of data, and an error occuring (e.g. terminating the application mid transfer).

The examples we've based our investigations on are the following.

https://thepracticaldeveloper.com/2017/11/04/full-reactive-stack-ii-the-angularjs-client/

http://javasampleapproach.com/reactive-programming/angular-4-spring-webflux-spring-data-reactive-mongodb-example-full-reactive-angular-4-http-client-spring-boot-restapi-server#25_Service

Both onerror and the completion function in the EventSource get called either when the data is send by spring successfully and reaches the end of the stream, which then closes the connection, or when we ctrl+c the application mid stream, or when we throw an exception randomly in the middle of sending data.

The EventSource argument just contains {type: 'error'} in all 3 cases.

回答1:

From what I understand, SSE streams are mainly about infinite streams; the spec doesn't seem to offer a standard way of signaling the end of a stream to clients (they will try to reconnect by default).

You could implement that in your controller, by returning a Flux<ServerSentEvent> and terminating the flux with a custom event:

return Flux.concat(
    fetchUserEvents(),
    Flux.just(ServerSentEvent.builder().event("disconnect").build()
);

On the client side, you could correctly close the connection when you're done, leaving all other use cases as errors and letting the browser reconnecting automatically:

evtSource.addEventListener("disconnect", function(e) {
    evtSource.close();
}, false);

This is rather annoying, so I've raised SPR-16761 to improve SSE support there.