Stručný sprievodca časovými limitmi v OkHttp

1. Prehľad

V tomto rýchlom návode sa zameriame na rôzne typy časových limitov, ktoré môžeme nastaviť pre klienta OkHttp.

Všeobecnejší prehľad o knižnici OkHttp nájdete v našej úvodnej príručke OkHttp.

2. Časový limit pripojenia

Časový limit pripojenia definuje a časové obdobie, v ktorom by náš klient mal nadviazať spojenie s cieľovým hostiteľom.

V predvolenom nastavení pre OkHttpClient, tento časový limit je nastavený na 10 sekúnd.

Jeho hodnotu však môžeme ľahko zmeniť pomocou OkHttpClient.Builder # connectTimeout metóda. Hodnota nula znamená, že vôbec nevyprší časový limit.

Pozrime sa teraz, ako zostaviť a používať OkHttpClient s vlastným časovým limitom pripojenia:

@Test public void whenConnectTimeoutExceeded_thenSocketTimeoutException () {OkHttpClient client = new OkHttpClient.Builder () .connectTimeout (10, TimeUnit.MILLISECONDS) .build (); Request request = new Request.Builder () .url ("// 203.0.113.1") // neprispôsobiteľná adresa .build (); Throwable thrown = catchThrowable (() -> client.newCall (request) .execute ()); assertThat (vyhodené) .isInstanceOf (SocketTimeoutException.class); }

Vyššie uvedený príklad ukazuje, že klient hodí a SocketTimeoutException keď pokus o pripojenie prekročí nakonfigurovaný časový limit.

3. Časový limit čítania

Časový limit čítania sa použije od okamihu, keď sa úspešne nadviazalo spojenie medzi klientom a cieľovým hostiteľom.

Definuje a maximálny čas nečinnosti medzi dvoma dátovými paketmi pri čakaní na odpoveď servera.

The predvolený časový limit 10 sekúnd možno zmeniť pomocou OkHttpClient.Builder # readTimeout. Analogicky ako v prípade časového limitu pripojenia, nulová hodnota neznamená žiadny časový limit.

Pozrime sa teraz, ako nakonfigurovať vlastný časový limit čítania v praxi:

@Test public void whenReadTimeoutExceeded_thenSocketTimeoutException () {OkHttpClient client = new OkHttpClient.Builder () .readTimeout (10, TimeUnit.MILLISECONDS) .build (); Request request = new Request.Builder () .url ("// httpbin.org/delay/2") // 2-sekundový čas odozvy .build (); Throwable thrown = catchThrowable (() -> client.newCall (request) .execute ()); assertThat (vyhodené) .isInstanceOf (SocketTimeoutException.class); }

Ako vidíme, server nevráti odpoveď v rámci definovaného časového limitu 500 ms. Výsledkom je, že OkHttpClient hodí a SocketTimeoutException.

4. Časový limit zápisu

Časový limit zápisu definuje a maximálna doba nečinnosti medzi dvoma dátovými paketmi pri odosielaní žiadosti na server.

Podobne, čo sa týka časových limitov pripojenia a čítania, môžeme prepísať predvolenú hodnotu 10 sekúnd pomocou OkHttpClient.Builder # writeTimeout. Podľa konvencie nulová hodnota neznamená vôbec žiadny časový limit.

V nasledujúcom príklade nastavíme veľmi krátky časový limit zápisu 10 ms a na server pošleme obsah 1 MB:

@Test public void whenWriteTimeoutExceeded_thenSocketTimeoutException () {OkHttpClient client = new OkHttpClient.Builder () .writeTimeout (10, TimeUnit.MILLISECONDS) .build (); Žiadosť request = new Request.Builder () .url ("// httpbin.org/delay/2") .post (RequestBody.create (MediaType.parse ("text / plain"), create1MBString ())) .build ( ); Throwable thrown = catchThrowable (() -> client.newCall (request) .execute ()); assertThat (vyhodené) .isInstanceOf (SocketTimeoutException.class); }

Ako vidíme, kvôli veľkému užitočnému zaťaženiu náš klient nie je schopný poslať telo žiadosti na server v stanovenom časovom limite. V dôsledku toho OkHttpClient hodí a SocketTimeoutException.

5. Časový limit hovoru

Časový limit hovoru je trochu iný ako časové limity pre pripojenie, čítanie a zápis, o ktorých sme už hovorili.

Definuje časový limit pre úplné volanie HTTP. To zahŕňa riešenie DNS, pripojenie, zápis tela žiadosti, spracovanie servera, ako aj prečítanie tela odpovede.

Na rozdiel od iných časových limitov jeho predvolená hodnota je nastavená na nulu, čo neznamená žiadny časový limit. Ale samozrejme, môžeme nakonfigurovať vlastnú hodnotu pomocou OkHttpClient.Builder # callTimeout metóda.

Pozrime sa na praktický príklad použitia:

@Test public void whenCallTimeoutExceeded_thenInterruptedIOException () {OkHttpClient client = new OkHttpClient.Builder () .callTimeout (1, TimeUnit.SECONDS) .build (); Žiadosť request = new Request.Builder () .url ("// httpbin.org/delay/2") .build (); Throwable thrown = catchThrowable (() -> client.newCall (request) .execute ()); assertThat (vyhodený) .isInstanceOf (InterruptedIOException.class); }

Ako vidíme, je prekročený časový limit hovoru a OkHttpClient hodí Prerušená výnimka IO.

6. Časový limit na žiadosť

Odporúča sa vytvoriť jeden OkHttpClient inštanciu a znova ju použiť pre všetky volania HTTP v celej našej aplikácii.

Niekedy však vieme, že určitá požiadavka trvá dlhšie ako všetky ostatné. V tejto situácii musíme predĺžiť daný časový limit iba pre daný hovor.

V takýchto prípadoch môžeme použiť OkHttpClient # newBuilder metóda. Týmto sa vytvorí nový klient, ktorý zdieľa rovnaké nastavenia. Potom môžeme pomocou metód tvorcu upraviť nastavenie časového limitu podľa potreby.

Pozrime sa teraz, ako to urobiť v praxi:

@Test public void whenPerRequestTimeoutExtended_thenResponseSuccess () hodí IOException {OkHttpClient defaultClient = nový OkHttpClient.Builder () .readTimeout (1, TimeUnit.SECONDS) .build (); Žiadosť request = new Request.Builder () .url ("// httpbin.org/delay/2") .build (); Throwable thrown = catchThrowable (() -> defaultClient.newCall (request) .execute ()); assertThat (vyhodené) .isInstanceOf (InterruptedIOException.class); OkHttpClient extendedTimeoutClient = defaultClient.newBuilder () .readTimeout (5, TimeUnit.SECONDS) .build (); Odozva odpovede = extendedTimeoutClient.newCall (požiadavka) .execute (); assertThat (response.code ()). isEqualTo (200); }

Ako vidíme defaultClient sa nepodarilo dokončiť volanie HTTP z dôvodu prekročeného časového limitu čítania.

Preto sme vytvorili extendedTimeoutClient, upravil hodnotu časového limitu a úspešne vykonal požiadavku.

7. Zhrnutie

V tomto článku sme preskúmali rôzne časové limity, ktoré môžeme nakonfigurovať pre OkHttpClient.

Krátko sme tiež opísali, kedy sa počas hovoru HTTP použijú časové limity pripojenia, čítania a zápisu.

Navyše, ukázali sme, aké ľahké je zmeniť určitú hodnotu časového limitu iba pre jednu požiadavku.

Ako obvykle sú všetky príklady kódov k dispozícii na GitHub.


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