So stellen Sie das Verbindungszeitlimit mit OkHttp ein

173

Ich entwickle eine App mit der OkHttp-Bibliothek und habe das Problem, dass ich nicht feststellen kann, wie das Verbindungszeitlimit und das Socket-Zeitlimit festgelegt werden.

OkHttpClient client = new OkHttpClient();

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

Response response = client.newCall(request).execute();
Kelvinzer
quelle
2
Die von Ihnen ausgewählte Antwort ist nicht mehr gültig. Vielleicht sollten Sie die Frage bearbeiten, um die Version von okhttp anzugeben.
Theyouthis

Antworten:

324

Sie müssen dies einfach tun

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

Beachten Sie, dass der eingestellte Wert setReadTimeoutderjenige ist, setSoTimeoutder Socketintern im Internet verwendet wirdOkHttp Connection Klasse verwendet wird.

Das Nichteinstellen einer Zeitüberschreitung auf dem OkHttpCliententspricht dem Festlegen eines Werts von 0auf setConnectTimeoutoder setReadTimeoutund führt zu keiner Zeitüberschreitung. Beschreibung kann gefunden werden hier .

Wie von @marceloquinta in den Kommentaren erwähnt setWriteTimeout kann auch eingestellt werden.

Ab Version 2.5.0 sind die Zeitlimitwerte für Lesen, Schreiben und Verbinden standardmäßig auf 10 Sekunden festgelegt, wie von @ChristerNordvik angegeben. Dies kann hier gesehen werden .

Ab OkHttp3 kann dies nun über den Builder so geschehen

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

Sie können das Rezept auch hier anzeigen .

Miguel Lavigne
quelle
6
Gibt es eine Möglichkeit, dieses Zeitlimit für jede Anforderung unterschiedlich festzulegen (jede Anforderung hat denselben statischen Client)?
StErMi
3
Sie können für jede Anfrage ein bestimmtes Zeitlimit festlegen: Hier einige Informationen: github.com/square/okhttp/wiki/Recipes
Tobliug
3
Vergessen Sie nicht das WRITE-Timeout: client.setWriteTimeout (10, TimeUnit.SECONDS);
Marceloquinta
7
@ MiguelLavigne Nur zu Ihrer Information, OkHttp wurde in 2.5.0 geändert, um ein Standardzeitlimit von 10 Sekunden zu haben.
Christer Nordvik
5
Veraltete Antwort
devDeejay
143

Für okhttp3 hat sich dies etwas geändert.

Jetzt richten Sie die Zeiten mit dem Builder ein und nicht mit Setzern wie folgt:

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

Weitere Informationen finden Sie in ihrem Wiki: https://github.com/square/okhttp/blob/b3dcb9b1871325248fba917458658628c44ce8a3/docs/recipes.md#timeouts-kt-java

Kaizie
quelle
12

Für die Nachrüstung von Retrofit: 2.0.0-beta4 lautet der Code wie folgt

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();
Sam
quelle
9

Für Retrofit 2.0.0-beta1 oder beta2 lautet der Code wie folgt

    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();
xaxist
quelle
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();
Mohammad nabil
quelle
5

Es hat sich jetzt geändert. Ersetzen.Builder() durch.newBuilder()

Ab okhttp: 3.9.0 lautet der Code wie folgt:

OkHttpClient okHttpClient = new OkHttpClient()
    .newBuilder()
    .connectTimeout(10,TimeUnit.SECONDS)
    .writeTimeout(10,TimeUnit.SECONDS)
    .readTimeout(30,TimeUnit.SECONDS)
    .build();
Löwe
quelle
5

okhttp version: 3.11.0oder höher

aus okhttp Quellcode

/**
 * 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 kann ein beliebiger Wert von unten sein

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

Beispielcode

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

Aktualisiert

Ich habe eine neue API zu okhttp von der Version hinzugefügt 3.12.0, Sie können Timeout wie folgt einstellen:

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

HINWEIS: Dies erfordert API 26+. Wenn Sie ältere Versionen von Android unterstützen, verwenden Sie diese weiterhin (5, TimeUnit.SECONDS).

Shellhub
quelle
4

wie so:

//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();
Joolah
quelle
4

Das hat bei mir funktioniert ... von 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();
Henderson
quelle
2

Wenn Sie die Konfiguration anpassen möchten, verwenden Sie zuerst die folgende Methode, um OKhttpclient zu erstellen, und fügen Sie dann einen Builder hinzu.

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);
    }
Sandhya Murugesan
quelle
1

Sie können ein Anrufzeitlimit festlegen, das den gesamten Zyklus abdeckt, indem DNS aufgelöst, eine Verbindung hergestellt, der Anforderungshauptteil geschrieben, der Server verarbeitet und der Antworttext gelesen wird.

val client = OkHttpClient().newBuilder().callTimeout(CALL_TIMEOUT_IN_MINUTES, TimeUnit.MINUTES).build()
ChaturaM
quelle