Ao raelizar uma chamada de API localmente utilizando o OkHttpClient, você pode encontrar erros de timeout, como indicado nos registros de exceção abaixo:
Exception in thread "main" java.net.SocketTimeoutException: timeout
at okio.Okio$4.newTimeoutException(Okio.java:230)
at okio.AsyncTimeout.exit(AsyncTimeout.java:285)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:241)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:345)
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:217)
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:211)
at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:189)
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:75)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
... (mais 20 linhas)
Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at okio.Okio$2.read(Okio.java:139)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:237)
... (mais 21 linhas)
A causa raiz deste problema é frequentemente que o processamento da API no servidor demora mais do que o tempo de resposta que o cliente está disposto a esperar. Para resolver, é necessário configurar os tempos de timeout do OkHttpClient para valores mais adequados. Aumentar os limites de conexão e leitura para 50 segundos, por exemplo, pode resolver o problema. Veja o código a seguir:
int tempoLimite = 50000; // milissegundos
OkHttpClient httpClient = new OkHttpClient.Builder()
.connectTimeout(tempoLimite, TimeUnit.MILLISECONDS)
.readTimeout(tempoLimite, TimeUnit.MILLISECONDS)
.build();
Alguns desenvolvedores sugerem a configuração dos tempos de timeout usando métodos do tipo set diretamente na instância do cliente, como mostrado no exemplo abaixo:
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(30, TimeUnit.SECONDS); // tempo de conexão
client.setReadTimeout(30, TimeUnit.SECONDS); // tempo de leitura do socket
No entanto, tal abordagem não é suportada pela API atual do OkHttp. A classe OkHttpClient é projetada como imutável; suas configurações são definidas no momento da construção e não podem ser alteradas posteriormente. Portanto, a utilização do Builder é o método correto e recomendado para definir os tempos de timeout.