如何解决面对 io.netty.handler.timeout.ReadTimeoutException:在使用服务器发送的事件时为 null
我是 Spring Web Flux 的新手,我有一个客户端应用程序,它使用服务器发送的事件,事件由服务器随机发布,没有固定的延迟。但是如果没有事件,消费者会在 60 秒后抛出 io.netty.handler.timeout.ReadTimeoutException: null
服务端事件消费者代码
webClient.get()
.uri("http://localhost:8080/events")
.accept(MediaType.TEXT_EVENT_STREAM)
.retrieve()
.bodyToFlux(type)
.subscribe(event -> process(event));
即使长时间没有事件,我也需要连接客户端。
完全异常
[36mr.netty.http.client.HttpClientConnect [...] The connection observed an error
io.netty.handler.timeout.ReadTimeoutException: null
reactor.Flux.MonoFlatMapMany.1 onError(org.springframework.web.reactive.function.client.WebClientRequestException: nested exception is io.netty.handler.timeout.ReadTimeoutException)
reactor.Flux.MonoFlatMapMany.1
org.springframework.web.reactive.function.client.WebClientRequestException: nested exception is io.netty.handler.timeout.ReadTimeoutException
at org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$wrapException$9(ExchangeFunctions.java:141) ~[spring-webflux-5.3.5.jar:5.3.5]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
解决方法
在 Mozilla description for server sent events 中有一个注释:
冒号作为一行的第一个字符本质上是一个注释,并且 被忽略。 注意:注释行可用于防止连接 从超时;服务器可以定期发送评论以保持 连接活着。
所以定期发送评论可以保持连接活跃。那么我们如何发送评论?
Well spring 的类 ServerSentEvent 具有函数 ServerSentEvent#comment。因此,如果我们将此类与实例 Flux#interval 结合使用,我们可以合并仅包含评论 keep alive
的事件。
这是我不久前构建的一个项目的示例
@Bean
public RouterFunction<ServerResponse> foobars() {
return route()
.path("/api",builder -> builder
.GET("/foobar/{id}",accept(TEXT_EVENT_STREAM),request -> ok()
.contentType(MediaType.TEXT_EVENT_STREAM)
.header("Cache-Control","no-transform")
.body(Flux.merge(foobarHandler.stream(request.pathVariable("id")),Flux.interval(Duration.ofSeconds(15)).map(aLong -> ServerSentEvent.<List<FoobarResponse>>builder()
.comment("keep alive").build())),new ParameterizedTypeReference<ServerSentEvent<List<FoobarResponse>>>(){}))
.build();
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。