问题
Working with spring reactive application, I created a rest service which produces an event every second. The code for my rest controller is:
@GetMapping(value = "/events", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Event> getEvents() {
Flux<Event> eventFlux = Flux.fromStream(Stream.generate(() -> new Event(new Random().nextLong(), "Hello Event")));
Flux<Long> emmitFlux = Flux.interval(Duration.ofSeconds(1));
return Flux.zip(eventFlux, emmitFlux).map(Tuple2::getT1);
}
The application runs fine at the url: localhost:8080/events in the browser. I get a new event every second. But when I close the browser I get the following error:
java.io.IOException: An established connection was aborted by the software in your host machine
Have anyone faced and resolved any similar issue with spring-reactive?
回答1:
You see this message because Spring WebFlux has no proper way to differentiate a regular SSE stream cancellation from a unexpected connection closing due to network connectivity issue for example.
We even filter some typical messages like "broken pipe", but I guess you are on windows and exception messages are localized so we can't do that in a reliable way.
That said as part of SPR-16688 which will be available as of Spring Framework 5.0.6 / Spring Boot 2.0.2, we have improved the logging for such use case in order to make it more relevant:
- Reactor Netty does not log errors in addition to throwing the exception, see reactor-netty#339
- WebFlux server now uses warning error log level instead of error
- Only the message is printed in the log, not the stacktrace which is mostly useless in reactive world
来源:https://stackoverflow.com/questions/49967213/spring-reactive-java-io-ioexception-an-established-connection-was-aborted-by-t