En hurtig guide til timeouts i OkHttp

1. Oversigt

I denne hurtige vejledning fokuserer vi på forskellige typer timeouts, vi kan indstille til OkHttp-klienten.

For den mere generelle oversigt over OkHttp-biblioteket, se vores indledende OkHttp-guide.

2. Tilslut timeout

En forbindelses-timeout definerer a tidsperiode, hvor vores klient skal oprette forbindelse til en målvært.

Som standard for OkHttpClient, denne timeout er indstillet til 10 sekunder.

Vi kan dog let ændre dens værdi ved hjælp af OkHttpClient.Builder # connectTimeout metode. En værdi på nul betyder slet ingen timeout.

Lad os nu se, hvordan man bygger og bruger en OkHttpClient med en tilpasset forbindelsestimeout:

@Test offentlig ugyldig nårConnectTimeoutExceeded_thenSocketTimeoutException () {OkHttpClient client = new OkHttpClient.Builder () .connectTimeout (10, TimeUnit.MILLISECONDS) .build (); Anmodningsanmodning = ny Request.Builder () .url ("// 203.0.113.1") // ikke-routbar adresse .build (); Kastbar kastet = catchThrowable (() -> client.newCall (anmodning). Udfør ()); assertThat (kastet) .isInstanceOf (SocketTimeoutException.class); }

Ovenstående eksempel viser, at klienten kaster et SocketTimeoutException når forbindelsesforsøget overstiger den konfigurerede timeout.

3. Læs Timeout

En læsetimeout anvendes fra det øjeblik, forbindelsen mellem en klient og en målvært er etableret med succes.

Det definerer en maksimal inaktivitetstid mellem to datapakker, når du venter på serverens svar.

Det standard timeout på 10 sekunder kan ændres ved hjælp af OkHttpClient.Builder # readTimeout. Analogt som for forbindelsestimeout angiver en nulværdi ingen timeout.

Lad os nu se, hvordan man konfigurerer en brugerdefineret læsetimeout i praksis:

@Test offentlig ugyldig nårReadTimeoutExceeded_thenSocketTimeoutException () {OkHttpClient client = new OkHttpClient.Builder () .readTimeout (10, TimeUnit.MILLISECONDS) .build (); Anmodningsanmodning = ny Request.Builder () .url ("// httpbin.org/delay/2") // 2-sekunders responstid .build (); Kastbar kastet = catchThrowable (() -> client.newCall (anmodning). Udfør ()); assertThat (kastet) .isInstanceOf (SocketTimeoutException.class); }

Som vi kan se, returnerer serveren ikke svaret inden for den definerede timeout på 500 ms. Som et resultat af dette OkHttpClient kaster en SocketTimeoutException.

4. Skriv timeout

En skrive-timeout definerer en maksimal inaktivitetstid mellem to datapakker, når anmodningen sendes til serveren.

På samme måde som for tilslutning og læsning af timeouts, vi kan tilsidesætte standardværdien på 10 sekunder ved hjælp af OkHttpClient.Builder # writeTimeout. Som en konvention betyder en nulværdi slet ingen timeout.

I det følgende eksempel indstiller vi en meget kort skrivetid på 10 ms og sender et 1 MB indhold til serveren:

@Test offentlig ugyldigt nårWriteTimeoutExceeded_thenSocketTimeoutException () {OkHttpClient-klient = ny OkHttpClient.Builder () .writeTimeout (10, TimeUnit.MILLISECONDS) .build (); Anmodningsanmodning = ny Request.Builder () .url ("// httpbin.org/delay/2") .post (RequestBody.create (MediaType.parse ("text / plain"), create1MBString ())) .build ( ); Kastbar kastet = catchThrowable (() -> client.newCall (anmodning). Udfør ()); assertThat (kastet) .isInstanceOf (SocketTimeoutException.class); }

Som vi ser, på grund af den store nyttelast, er vores klient ikke i stand til at sende et anmodningsorgan til serveren inden for den definerede timeout. Derfor er den OkHttpClient kaster en SocketTimeoutException.

5. Ring til timeout

En timeout for opkald er lidt anderledes end de forbindelses-, læse- og skrive-timeouts, vi allerede har diskuteret.

Den definerer en tidsbegrænsning for et komplet HTTP-opkald. Dette inkluderer løsning af DNS, tilslutning, skrivning af anmodningslegemet, serverbehandling samt læsning af svartekst.

I modsætning til andre timeouts, standardværdien er sat til nul, hvilket ikke medfører nogen timeout. Men selvfølgelig kan vi konfigurere en brugerdefineret værdi ved hjælp af OkHttpClient.Builder # callTimeout metode.

Lad os se et praktisk brugseksempel:

@Test offentlig ugyldig nårCallTimeoutExceeded_thenInterruptedIOException () {OkHttpClient client = new OkHttpClient.Builder () .callTimeout (1, TimeUnit.SECONDS) .build (); Anmodningsanmodning = ny Request.Builder () .url ("// httpbin.org/delay/2") .build (); Kastbar kastet = catchThrowable (() -> client.newCall (anmodning). Udfør ()); assertThat (kastet) .isInstanceOf (InterruptedIOException.class); }

Som vi kan se, overskrides timeout for opkald, og OkHttpClient kaster en AfbrudtIOException.

6. Timeout pr. Anmodning

Det anbefales at oprette en enkelt OkHttpClient forekomst og genbrug det til alle HTTP-opkald på tværs af vores ansøgning.

Nogle gange ved vi dog, at en bestemt anmodning tager mere tid end alle de andre. I denne situation er vi nødt til det forlæng kun en given timeout for det pågældende opkald.

I sådanne tilfælde kan vi bruge en OkHttpClient # newBuilder metode. Dette bygger en ny klient, der deler de samme indstillinger. Vi kan derefter bruge bygningsmetoderne til at justere timeout-indstillinger efter behov.

Lad os nu se, hvordan man gør dette i praksis:

@Test offentlig ugyldig nårPerRequestTimeoutExtended_thenResponseSuccess () kaster IOException {OkHttpClient defaultClient = ny OkHttpClient.Builder () .readTimeout (1, TimeUnit.SECONDS) .build (); Anmodningsanmodning = ny Request.Builder () .url ("// httpbin.org/delay/2") .build (); Kastbar kastes = catchThrowable (() -> defaultClient.newCall (anmodning). Udfør ()); assertThat (kastet) .isInstanceOf (InterruptedIOException.class); OkHttpClient extendedTimeoutClient = defaultClient.newBuilder () .readTimeout (5, TimeUnit.SECONDS) .build (); Svarrespons = extendedTimeoutClient.newCall (anmodning). Udfør (); assertThat (respons.code ()). er EqualTo (200); }

Som vi ser defaultClient mislykkedes at gennemføre HTTP-opkaldet på grund af den overskredne timeout for læsning.

Derfor skabte vi extendedTimeoutClient, justerede timeoutværdien og udførte anmodningen med succes.

7. Resume

I denne artikel, vi udforskede forskellige timeouts, vi kan konfigurere til OkHttpClient.

Vi beskrev også kort, hvornår forbindelses-, læse- og skrive-timeouts anvendes under et HTTP-opkald.

Derudover vi viste, hvor let det er kun at ændre en bestemt timeout-værdi for en enkelt anmodning.

Som sædvanligt er alle kodeeksempler tilgængelige på GitHub.


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