How to set a timeout in Spring 5 WebFlux WebClient
To set the read and connect timeout I use the method below, because the SO_TIMEOUT option is not available for channels using NIO (and giving the warning Unknown channel option 'SO_TIMEOUT' for channel '[id: 0xa716fcb2]'
)
ReactorClientHttpConnector connector = new ReactorClientHttpConnector( options -> options.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2000) .compression(true) .afterNettyContextInit(ctx -> { ctx.addHandlerLast(new ReadTimeoutHandler(5000, TimeUnit.MILLISECONDS)); }));return WebClient.builder() .clientConnector(connector) .build();
ReactorClientHttpConnector API changed in version Spring WebFlux 5.1.
So I do the following (Kotlin syntax, based on @joshiste example):
val tcpClient = TcpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10_000) .doOnConnected { connection -> connection.addHandlerLast(ReadTimeoutHandler(10)) .addHandlerLast(WriteTimeoutHandler(10)) }val myWebClient = webClientBuilder .clientConnector(ReactorClientHttpConnector(HttpClient.from(tcpClient))) .baseUrl(myEndPoint) .build()
UPDATE 2021
HttpClient.from in deprecated in last version of Reactive Netty. It was copying the configuration of the tcpClient. Now we can configure httpClient directly.
val httpClient = HttpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10_000) .doOnConnected { connection -> connection.addHandlerLast(ReadTimeoutHandler(10)) .addHandlerLast(WriteTimeoutHandler(10)) }val myWebClient = webClientBuilder .clientConnector(ReactorClientHttpConnector(httpClient)) .baseUrl(myEndPoint) .build()
As Spring Webflux was updated, here is a solution that works for Java (based on the answer for Kotlin):
TcpClient timeoutClient = TcpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, SECONDS*1000) .doOnConnected( c -> c.addHandlerLast(new ReadTimeoutHandler(SECONDS)) .addHandlerLast(new WriteTimeoutHandler(SECONDS)));return webClientBuilder.baseUrl(YOUR_URL) .clientConnector(new ReactorClientHttpConnector(HttpClient.from(timeoutClient))) .build();
UPDATE 2021
since HttpClient.from(TcpClient)
is deprectaed now it's even easier:
return WebClient.builder() .baseUrl(YOUR_URL) .clientConnector(new ReactorClientHttpConnector(HttpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, SECONDS * 1000) .doOnConnected(c -> c.addHandlerLast(new ReadTimeoutHandler(SECONDS)) .addHandlerLast(new WriteTimeoutHandler(SECONDS))))) .build();