[英]How do you get Client's IP address? (Spring WebFlux WebSocket)
[英]How do you disconnect an idle client in a Spring Webflux application?
我有一个spring-webflux
应用程序(引擎盖下有 Netty)。 有这样的 controller 方法:
public Mono<Response> submitBinaryData(@RequestHeader HttpHeaders headers,
@RequestBody(required = false) Flux<DataBuffer> data) {
return process(data.timeout(Duration.ofSeconds(10)), getContentLength(headers));
}
process()
方法不太有趣,它只是将二进制数据写入存储。 重要的是它预先知道有多少数据(通过Content-Length
标头)。
然后,假设我们有一个客户卡住了,像这样:
byte[] bufferOf1Mb = new byte[1024 * 1024];
HttpRequest request = HttpRequest.newBuilder(new URI("http://localhost:8080/")
.setHeader("Accept", "application/json")
.setHeader("Content-Type", "application/octet-stream")
.POST(BodyPublishers.fromPublisher(JdkFlowAdapter.publisherToFlowPublisher(
Flux.just(ByteBuffer.wrap(bufferOf1Mb)).concatWith(Flux.never())), 10 * bufferOf1Mb.length))
.build();
HttpResponse<String> httpResponse = client.send(request, BodyHandlers.ofString());
这个客户端宣布了 10Mb 的数据,但只写入了 1Mb,然后永远等待。
我希望这些客户端在超时后断开连接,以避免将资源浪费在可能永远损坏的客户端上。 在 controller 方法中,如果数据在一段时间内没有流动,则timeout()
运算符会引发TimeoutException
。 然后异常处理程序(未显示)捕获并处理异常:它仅向客户端返回Response
object(作为 JSON)。
问题是即使发生超时(可以在日志中看到),客户端也不会注意到任何事情。 客户端可能正在等待服务器使用其数据,然后才会查看响应。 但是输入永远不会被发送。 并且服务器不会关闭连接,因为它希望客户端读取响应。 所以连接永远保持打开状态。
调试器还显示,当这种情况发生时,会在响应 object 上调用writeWith()
和setComplete()
。
有没有办法断开这样的客户端? 使用超时设置(尽管server.netty.
只有一个与超时相关的设置, connection-timeout
,这不是这里需要的),或者以编程方式(当客户端明显丢失时,强行切断连接),或者以任何其他方式?
如果您使用 WebClient 处理 http 请求,您可以在构建 webclient 时在 httpClient 中设置 responseTimeout。
@Bean
public WebClient getWebClient(WebClient.Builder webClientBuilder) {
ClientHttpConnector connector = new ReactorClientHttpConnector(
HttpClient.create().responseTimeout(Duration.ofSeconds(10))
);
return webClientBuilder
.clientConnector(connector)
.build();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.