Come impostare il timeout della connessione con OkHttp


173

Sto sviluppando un'app utilizzando la libreria OkHttp e il mio problema è che non riesco a trovare come impostare il timeout della connessione e il timeout del socket.

OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder().url(url).build();

Response response = client.newCall(request).execute();

2
La risposta selezionata non è più valida. Forse dovresti modificare la domanda per specificare la versione di okhttp.
Theyouthis

Risposte:


324

Devi semplicemente farlo

OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(15, TimeUnit.SECONDS); // connect timeout
client.setReadTimeout(15, TimeUnit.SECONDS);    // socket timeout

Request request = new Request.Builder().url(url).build();
Response response = client.newCall(request).execute();

Essere consapevoli del fatto che il valore impostato in setReadTimeoutè quello usato nel setSoTimeoutsul Socketinternamente nelOkHttp Connection codice categoria.

Non impostare qualsiasi timeout sul OkHttpClientè l'equivalente di impostare un valore di 0on setConnectTimeouto setReadTimeoute si tradurrà in nessun timeout a tutti. La descrizione può essere trovata qui .

Come menzionato da @marceloquinta nei commenti setWriteTimeoutpuò anche essere impostato.

A partire dalla versione 2.5.0 i valori di timeout di lettura / scrittura / connessione sono impostati su 10 secondi per impostazione predefinita, come indicato da @ChristerNordvik. Questo può essere visto qui .

A partire da OkHttp3 ora puoi farlo attraverso il Builder in questo modo

client = new OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .writeTimeout(10, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .build();

Puoi anche visualizzare la ricetta qui .


6
C'è un modo per impostare quei timeout diversi per ogni richiesta (ogni richiesta ha lo stesso client statico)?
StErMi,

3
È possibile impostare un timeout specifico per ogni richiesta: Ecco alcune informazioni: github.com/square/okhttp/wiki/Recipes
Tobliug

3
Non dimenticare il timeout WRITE: client.setWriteTimeout (10, TimeUnit.SECONDS);
marceloquinta,

7
@MiguelLavigne FYI, OkHttp modificato in 2.5.0 per avere un timeout predefinito di 10 sec.
Christer Nordvik,

5
Risposta obsoleta
devDeejay


12

Per Retrofit retrofit: 2.0.0-beta4 il codice è il seguente

OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(logging)
        .connectTimeout(30, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS)
        .build();

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://api.yourapp.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .client(client)
        .build();

9

Per Retrofit 2.0.0-beta1 o beta2, il codice è il seguente

    OkHttpClient client = new OkHttpClient();

    client.setConnectTimeout(30, TimeUnit.SECONDS);
    client.setReadTimeout(30, TimeUnit.SECONDS);
    client.setWriteTimeout(30, TimeUnit.SECONDS);

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://api.yourapp.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();

7
//add in gradle and sync
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.google.code.gson:gson:2.6.2'

import okhttp3.OkHttpClient;
import okhttp3.OkHttpClient.Builder;


Builder b = new Builder();
b.readTimeout(200, TimeUnit.MILLISECONDS);
b.writeTimeout(600, TimeUnit.MILLISECONDS);
// set other properties

OkHttpClient client = b.build();

5

Adesso è cambiato. Sostituisci .Builder()con.newBuilder()

A partire da okhttp: 3.9.0 il codice è il seguente:

OkHttpClient okHttpClient = new OkHttpClient()
    .newBuilder()
    .connectTimeout(10,TimeUnit.SECONDS)
    .writeTimeout(10,TimeUnit.SECONDS)
    .readTimeout(30,TimeUnit.SECONDS)
    .build();

5

versione okhttp:3.11.0 o successiva

dal codice sorgente okhttp

/**
 * Sets the default connect timeout for new connections. A value of 0 means no timeout,
 * otherwise values must be between 1 and {@link Integer#MAX_VALUE} when converted to
 * milliseconds.
 *
 * <p>The connectTimeout is applied when connecting a TCP socket to the target host.
 * The default value is 10 seconds.
 */
public Builder connectTimeout(long timeout, TimeUnit unit) {
  connectTimeout = checkDuration("timeout", timeout, unit);
  return this;
}

unit può essere qualsiasi valore di seguito

TimeUnit.NANOSECONDS
TimeUnit.MICROSECONDS
TimeUnit.MILLISECONDS
TimeUnit.SECONDS
TimeUnit.MINUTES
TimeUnit.HOURS
TimeUnit.DAYS

codice di esempio

OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(5000, TimeUnit.MILLISECONDS)/*timeout: 5 seconds*/
        .build();

String url = "https://www.google.com";
Request request = new Request.Builder()
        .url(url)
        .build();

try {
    Response response = client.newCall(request).execute();
} catch (IOException e) {
    e.printStackTrace();
}

aggiornato

Ho aggiunto nuove API a okhttp dalla versione 3.12.0, puoi impostare il timeout in questo modo:

OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(Duration.ofSeconds(5))/*timeout: 5 seconds*/
        .build();

NOTA: questo richiede API 26+, quindi se supporti le versioni precedenti di Android, continua a utilizzare (5, TimeUnit.SECONDS).


4

così:

//New Request
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
        final OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(logging)
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .build();

4

questo ha funzionato per me ... da https://github.com/square/okhttp/issues/3553

OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .readTimeout(10, TimeUnit.SECONDS)
        .writeTimeout(10, TimeUnit.SECONDS)
        .retryOnConnectionFailure(false) <-- not necessary but useful!
        .build();

2

Se si desidera personalizzare la configurazione, utilizzare prima la metodologia seguente per creare prima OKhttpclient e quindi aggiungere il builder sopra di esso.

private final OkHttpClient client = new OkHttpClient();

// Copy to customize OkHttp for this request.
    OkHttpClient client1 = client.newBuilder()
        .readTimeout(500, TimeUnit.MILLISECONDS)
        .build();
    try (Response response = client1.newCall(request).execute()) {
      System.out.println("Response 1 succeeded: " + response);
    } catch (IOException e) {
      System.out.println("Response 1 failed: " + e);
    }

1

È possibile impostare un timeout di chiamata per coprire l'intero ciclo dalla risoluzione del DNS, alla connessione, alla scrittura del corpo della richiesta, all'elaborazione del server e alla lettura del corpo della risposta.

val client = OkHttpClient().newBuilder().callTimeout(CALL_TIMEOUT_IN_MINUTES, TimeUnit.MINUTES).build()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.