Spring 被动:java.io.IOException:当我关闭连接时,已建立的连接被您主机中的软件中止
Spring Reactive: java.io.IOException: An established connection was aborted by the software in your host machine, when I close the connection
使用 spring 反应式应用程序,我创建了一个每秒产生一个事件的休息服务。我的休息控制器的代码是:
@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);
}
应用程序在浏览器中的 url: localhost:8080/events 运行良好。我每秒都会收到一个新事件。但是当我关闭浏览器时,出现以下错误:
java.io.IOException: An established connection was aborted by the software in your host machine
有没有人遇到并解决了与 spring-reactive 的任何类似问题?
您看到此消息是因为 Spring WebFlux 没有正确的方法来区分常规 SSE 流取消和由于网络连接问题导致的意外连接关闭。
我们甚至过滤了一些典型的消息,例如 "broken pipe",但我猜您在 windows 上并且异常消息已本地化,因此我们无法以可靠的方式进行过滤。
作为 SPR-16688 的一部分,它将在 Spring Framework 5.0.6 / Spring Boot 2.0.2 中可用,我们改进了此类用例的日志记录为了使其更具相关性:
- Reactor Netty 除了抛出
例外情况,请参阅 reactor-netty#339
- WebFlux 服务器现在使用警告错误日志级别而不是错误
- 日志中只打印消息,而不是在反应世界中几乎没用的堆栈跟踪
使用 spring 反应式应用程序,我创建了一个每秒产生一个事件的休息服务。我的休息控制器的代码是:
@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);
}
应用程序在浏览器中的 url: localhost:8080/events 运行良好。我每秒都会收到一个新事件。但是当我关闭浏览器时,出现以下错误:
java.io.IOException: An established connection was aborted by the software in your host machine
有没有人遇到并解决了与 spring-reactive 的任何类似问题?
您看到此消息是因为 Spring WebFlux 没有正确的方法来区分常规 SSE 流取消和由于网络连接问题导致的意外连接关闭。
我们甚至过滤了一些典型的消息,例如 "broken pipe",但我猜您在 windows 上并且异常消息已本地化,因此我们无法以可靠的方式进行过滤。
作为 SPR-16688 的一部分,它将在 Spring Framework 5.0.6 / Spring Boot 2.0.2 中可用,我们改进了此类用例的日志记录为了使其更具相关性:
- Reactor Netty 除了抛出 例外情况,请参阅 reactor-netty#339
- WebFlux 服务器现在使用警告错误日志级别而不是错误
- 日志中只打印消息,而不是在反应世界中几乎没用的堆栈跟踪