How to set a timeout in Spring 5 WebFlux WebClient How to set a timeout in Spring 5 WebFlux WebClient spring spring

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();