Kratki vodič za vremenska ograničenja u OkHttpu

1. Pregled

U ovom brzom vodiču usredotočit ćemo se na različite vrste vremenskih ograničenja koja možemo postaviti za klijenta OkHttp.

Općenitiji pregled biblioteke OkHttp potražite u našem uvodnom vodiču za OkHttp.

2. Povežite vremensko ograničenje

Vremensko ograničenje povezivanja definira a vremensko razdoblje u kojem bi naš klijent trebao uspostaviti vezu s ciljnim hostom.

Prema zadanim postavkama za OkHttpClient, ovo je vremensko ograničenje postavljeno na 10 sekundi.

Međutim, njegovu vrijednost možemo lako promijeniti pomoću OkHttpClient.Builder # connectTimeout metoda. Vrijednost nula znači da uopće nema vremenskog ograničenja.

Pogledajmo sada kako graditi i koristiti OkHttpClient s prilagođenim vremenskim ograničenjem veze:

@Test public void whenConnectTimeoutExceeded_thenSocketTimeoutException () {OkHttpClient client = new OkHttpClient.Builder () .connectTimeout (10, TimeUnit.MILLISECONDS) .build (); Zahtjev za zahtjevom = novi Request.Builder () .url ("// 203.0.113.1") // adresa koja se ne može usmjeriti .build (); Bačeno bacanje = catchThrowable (() -> client.newCall (zahtjev) .execute ()); assertThat (bačen) .isInstanceOf (SocketTimeoutException.class); }

Gornji primjer pokazuje da klijent baca a SocketTimeoutException kada pokušaj povezivanja premaši konfigurirano vremensko ograničenje.

3. Pročitajte vremensko ograničenje

Istek čitanja primjenjuje se od trenutka kada je uspješno uspostavljena veza između klijenta i ciljnog domaćina.

Definira a maksimalno vrijeme neaktivnosti između dva podatkovna paketa kada se čeka odgovor poslužitelja.

The zadani timeout od 10 sekundi može se mijenjati pomoću OkHttpClient.Builder # readTimeout. Analogno kao i vremensko ograničenje povezivanja, nulta vrijednost znači da nema vremenskog ograničenja.

Pogledajmo sada kako u praksi konfigurirati prilagođeno vrijeme čekanja:

@Test public void whenReadTimeoutExceeded_thenSocketTimeoutException () {OkHttpClient client = new OkHttpClient.Builder () .readTimeout (10, TimeUnit.MILLISECONDS) .build (); Zahtjev za zahtjevom = novi Request.Builder () .url ("// httpbin.org/delay/2") // vrijeme odziva od 2 sekunde .build (); Bacano bacanje = catchThrowable (() -> client.newCall (zahtjev) .execute ()); assertThat (bačen) .isInstanceOf (SocketTimeoutException.class); }

Kao što vidimo, poslužitelj ne vraća odgovor unutar definiranog vremena čekanja od 500 ms. Kao rezultat, OkHttpClient baca a SocketTimeoutException.

4. Napišite vremensko ograničenje

Vrijeme isteka definira a maksimalno vrijeme neaktivnosti između dva podatkovna paketa prilikom slanja zahtjeva na poslužitelj.

Slično tome, što se tiče vremenskih ograničenja povezivanja i čitanja, možemo nadjačati zadanu vrijednost od 10 sekundi pomoću OkHttpClient.Builder # writeTimeout. Kao dogovor, nulta vrijednost uopće ne znači vremensko ograničenje.

U sljedećem primjeru postavljamo vrlo kratko vrijeme ispisa od 10 ms i na poslužitelj objavljujemo sadržaj od 1 MB:

@Test public void whenWriteTimeoutExceeded_thenSocketTimeoutException () {OkHttpClient client = new OkHttpClient.Builder () .writeTimeout (10, TimeUnit.MILLISECONDS) .build (); Zahtjev za zahtjevom = novi Request.Builder () .url ("// httpbin.org/delay/2") .post (RequestBody.create (MediaType.parse ("text / plain", create1MBString ())) .build ( ); Bacano bacanje = catchThrowable (() -> client.newCall (zahtjev) .execute ()); assertThat (bačen) .isInstanceOf (SocketTimeoutException.class); }

Kao što vidimo, zbog velikog korisnog tereta, naš klijent ne može poslati tijelo zahtjeva na poslužitelj u definiranom vremenskom ograničenju. Slijedom toga, OkHttpClient baca a SocketTimeoutException.

5. Istek poziva

Vremensko ograničenje poziva malo se razlikuje od vremenskog ograničenja povezivanja, čitanja i pisanja o kojem smo već razgovarali.

Definira vremensko ograničenje za potpuni HTTP poziv. To uključuje rješavanje DNS-a, povezivanje, pisanje tijela zahtjeva, obradu poslužitelja, kao i čitanje tijela odgovora.

Za razliku od ostalih vremenskih ograničenja, to je zadana vrijednost postavljena na nulu što ne znači da je isteklo vrijeme. Ali naravno, možemo konfigurirati prilagođenu vrijednost pomoću OkHttpClient.Builder # callTimeout metoda.

Pogledajmo primjer praktične upotrebe:

@Test public void whenCallTimeoutExceeded_thenInterruptIOException () {OkHttpClient client = new OkHttpClient.Builder () .callTimeout (1, TimeUnit.SECONDS) .build (); Zahtjev za zahtjevom = novi Request.Builder () .url ("// httpbin.org/delay/2") .build (); Bacano bacanje = catchThrowable (() -> client.newCall (zahtjev) .execute ()); assertThat (bačen) .isInstanceOf (InterruptedIOException.class); }

Kao što vidimo, vremensko ograničenje poziva premašeno je i OkHttpClient baca an PrekinutoIOException.

6. Istek po zahtjevu

Preporučuje se stvaranje singla OkHttpClient instancu i ponovno je upotrijebite za sve HTTP pozive u cijeloj našoj aplikaciji.

Međutim, ponekad znamo da određeni zahtjev oduzima više vremena od svih ostalih. U ovoj situaciji trebamo produžiti određeno vremensko ograničenje samo za taj određeni poziv.

U takvim slučajevima možemo koristiti OkHttpClient # newBuilder metoda. Ovim se gradi novi klijent koji dijeli iste postavke. Tada možemo pomoću graditeljskih metoda prilagoditi postavke vremenskog ograničenja prema potrebi.

Pogledajmo sada kako to učiniti u praksi:

@Test public void whenPerRequestTimeoutExtended_thenResponseSuccess () baca IOException {OkHttpClient defaultClient = new OkHttpClient.Builder () .readTimeout (1, TimeUnit.SECONDS) .build (); Zahtjev za zahtjevom = novi Request.Builder () .url ("// httpbin.org/delay/2") .build (); Bacano bacanje = catchThrowable (() -> defaultClient.newCall (zahtjev) .execute ()); assertThat (bačen) .isInstanceOf (InterruptedIOException.class); OkHttpClient extendedTimeoutClient = defaultClient.newBuilder () .readTimeout (5, TimeUnit.SECONDS) .build (); Odgovor odgovora = extendedTimeoutClient.newCall (zahtjev) .execute (); assertThat (response.code ()). isEqualTo (200); }

Kao što vidimo defaultClient nije uspio dovršiti HTTP poziv zbog premašenog vremena čekanja.

Zbog toga smo stvorili extensionTimeoutClient, prilagodio vrijednost vremenskog ograničenja i uspješno izvršio zahtjev.

7. Sažetak

U ovom smo članku istraživao različita vremenska ograničenja koja možemo konfigurirati za OkHttpClient.

Također smo ukratko opisali kada se tijekom HTTP poziva primjenjuju vremenska ograničenja povezivanja, čitanja i pisanja.

Dodatno, pokazali smo kako je lako promijeniti određenu vrijednost vremenskog ograničenja samo za jedan zahtjev.

Kao i obično, svi primjeri koda dostupni su na GitHubu.


$config[zx-auto] not found$config[zx-overlay] not found