我正在使用Spring WebClient从我的服务器接收服务器发送事件(由Spring SSEEmitter发布)。它工作正常,但是由于某种原因,我的服务器会定期在新行中发布字符串“ 0”。发生这种情况时,WebClient将关闭连接。
我挖了一下并打开Spring调试,发现以下信息:
+--------------------...+
| 0 1 2 3 4 5 ... |
| 30 0d 0a 0d 0a ...-|0.... |
[reactor.ipc.netty.http.client.HttpClientOperations:218] Received last HTTP packet
[reactor.ipc.netty.http.client.HttpClient:71] - USER_EVENT: [Handler Terminated]
[reactor.ipc.netty.channel.ChannelOperationsHandler:218] - Disposing context reactor.ipc.netty.channel.PooledClientContextHandler@45a97ad8
[reactor.ipc.netty.channel.PooledClientContextHandler:218] - Releasing channel:
[reactor.ipc.netty.resources.DefaultPoolResources:218] - Released, now 0 active connections
[reactor.ipc.netty.http.client.HttpClient:71] - READ COMPLETE
[reactor.ipc.netty.http.client.HttpClient:71] - READ COMPLETE
[reactor.ipc.netty.http.client.HttpClient:71] - CLOSE
[reactor.ipc.netty.http.client.HttpClient:71] - INACTIVE
[reactor.ipc.netty.http.client.HttpClient:71] - UNREGISTERED
很明显,WebClient内部使用Netty HttpClient,并且此客户端将字符串“ 0”视为“ lastHttpMessage”,然后关闭连接。
我的问题:
答案 0 :(得分:1)
您看到的"0"
是HTTP规范的一部分-当服务器发送HTTP分块响应时,大小为0的分块表示响应已完成。
我不认为我们可以在Netty中进行任何配置来更改此设置,也不认为应该这样做,因为这是HTTP的预期行为。
现在,我想知道为什么服务器首先发送它。您服务器上的Flux
可能已到达尽头并正在发送onComplete
信号,从而终止了响应。您的服务器实现中可能会有一些东西可以完成流。
您可以通过在管道中添加log
Reactor运算符来查看服务器中正在发生的事情,以查看哪个部分正在发送onComplete
信号。如果您有向我们展示的代码片段,我想您可以提出另一个问题,因为这个问题对于Spring社区已经非常有用,并且使其变得更加复杂也无济于事。
Spring Framework将通过WebClient
支持其他客户端库-例如,Jetty客户端(请参阅问题SPR-15092。但是我认为使用其他客户端不会解决此问题,因为它符合HTTP,而不是特定于客户端的行为。
答案 1 :(得分:1)
我发现如果我使用“ repeat”,则连接完成后Flux将自动重新连接。真好!
final Flux<Object> stream = WebClient
.create("http://localhost:8080/ssp")
.get().uri("/common/v1/eventstream")
.retrieve()
.bodyToFlux(ServerSentEvent.class)
.flatMap(e -> Mono.justOrEmpty(e.data()))
.repeat();
stream.subscribe(e -> System.out.println(e));