1. Gambaran keseluruhan
Dalam tutorial ringkas ini, kami akan menumpukan pada pelbagai jenis jangka masa yang dapat kami tetapkan untuk klien OkHttp.
Untuk gambaran umum yang lebih umum mengenai perpustakaan OkHttp, periksa panduan OkHttp pengenalan kami.
2. Sambungkan Timeout
Waktu tunggu sambung menentukan jangka masa di mana pelanggan kami harus menjalin hubungan dengan host sasaran .
Secara lalai, untuk OkHttpClient , timeout ini ditetapkan kepada 10 saat .
Walau bagaimanapun, kita dapat mengubah nilainya dengan mudah menggunakan kaedah OkHttpClient.Builder # connectTimeout . Nilai sifar bermaksud tidak habis masa sama sekali.
Sekarang mari kita lihat bagaimana membina dan menggunakan OkHttpClient dengan tamat masa sambungan tersuai:
@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") // non routable address .build(); Throwable thrown = catchThrowable(() -> client.newCall(request).execute()); assertThat(thrown).isInstanceOf(SocketTimeoutException.class); }
Contoh di atas menunjukkan bahawa pelanggan melemparkan SocketTimeoutException apabila percubaan sambungan melebihi batas waktu yang dikonfigurasi.
3. Baca Timeout
Batas waktu baca diterapkan sejak hubungan antara klien dan host sasaran berjaya dijalin.
Ini menentukan masa maksimum tidak aktif antara dua paket data ketika menunggu tindak balas pelayan .
Waktu tamat lalai 10 saat boleh diubah menggunakan OkHttpClient.Builder # readTimeout . Secara analognya, untuk masa tamat sambungan, nilai sifar menunjukkan tiada masa tamat.
Sekarang mari kita lihat cara mengkonfigurasi waktu tamat baca khusus dalam praktik:
@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-second response time .build(); Throwable thrown = catchThrowable(() -> client.newCall(request).execute()); assertThat(thrown).isInstanceOf(SocketTimeoutException.class); }
Seperti yang kita lihat, pelayan tidak mengembalikan respons dalam jangka masa tamat 500 ms. Akibatnya, OkHttpClient melemparkan SocketTimeoutException.
4. Tulis Waktu Tamat
Waktu tamat menulis menentukan masa maksimum tidak aktif antara dua paket data semasa menghantar permintaan ke pelayan.
Begitu juga, untuk masa tamat sambung dan baca, kita dapat mengatasi nilai lalai 10 saat menggunakan OkHttpClient.Builder # writeTimeout . Sebagai konvensyen, nilai sifar bermaksud tidak habis masa sama sekali.
Dalam contoh berikut, kami menetapkan masa tamat penulisan yang sangat pendek 10 ms dan menghantar kandungan 1 MB ke pelayan:
@Test public void whenWriteTimeoutExceeded_thenSocketTimeoutException() { OkHttpClient client = new OkHttpClient.Builder() .writeTimeout(10, TimeUnit.MILLISECONDS) .build(); Request 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(thrown).isInstanceOf(SocketTimeoutException.class); }
Seperti yang kita lihat, kerana muatan yang besar, pelanggan kami tidak dapat mengirim badan permintaan ke pelayan dalam jangka masa yang ditentukan. Akibatnya, OkHttpClient membuang SocketTimeoutException .
5. Tamat Waktu Panggilan
Tamat masa panggilan sedikit berbeza daripada tamat waktu sambung, baca dan tulis yang telah kita bincangkan.
Ini menentukan had masa untuk panggilan HTTP lengkap . Ini termasuk menyelesaikan DNS, menghubungkan, menulis badan permintaan, memproses pelayan, dan juga membaca badan respons.
Tidak seperti waktu tunggu yang lain, nilai lalai ditetapkan ke sifar yang tidak bermaksud tiada masa tamat . Tetapi tentu saja, kita dapat mengkonfigurasi nilai tersuai menggunakan kaedah OkHttpClient.Builder # callTimeout .
Mari lihat contoh penggunaan praktikal:
@Test public void whenCallTimeoutExceeded_thenInterruptedIOException() { OkHttpClient client = new OkHttpClient.Builder() .callTimeout(1, TimeUnit.SECONDS) .build(); Request request = new Request.Builder() .url("//httpbin.org/delay/2") .build(); Throwable thrown = catchThrowable(() -> client.newCall(request).execute()); assertThat(thrown).isInstanceOf(InterruptedIOException.class); }
Seperti yang kita dapat lihat, tamat masa panggilan itu melebihi dan OkHttpClient melemparkan yang InterruptedIOException.
6. Waktu Keluar Permintaan
Sebaiknya buat satu contoh OkHttpClient dan gunakan semula untuk semua panggilan HTTP di seluruh aplikasi kami.
Kadang-kadang, kita tahu bahawa permintaan tertentu memerlukan lebih banyak masa daripada yang lain. Dalam keadaan ini, kita perlu memperpanjang waktu tunggu tertentu untuk panggilan tertentu .
Dalam kes sedemikian, kita boleh menggunakan kaedah OkHttpClient # newBuilder . Ini membina klien baru yang berkongsi tetapan yang sama. Kami kemudian dapat menggunakan kaedah pembangun untuk menyesuaikan tetapan waktu tunggu yang diperlukan.
Mari kita lihat bagaimana melakukan ini dalam praktik:
@Test public void whenPerRequestTimeoutExtended_thenResponseSuccess() throws IOException { OkHttpClient defaultClient = new OkHttpClient.Builder() .readTimeout(1, TimeUnit.SECONDS) .build(); Request request = new Request.Builder() .url("//httpbin.org/delay/2") .build(); Throwable thrown = catchThrowable(() -> defaultClient.newCall(request).execute()); assertThat(thrown).isInstanceOf(InterruptedIOException.class); OkHttpClient extendedTimeoutClient = defaultClient.newBuilder() .readTimeout(5, TimeUnit.SECONDS) .build(); Response response = extendedTimeoutClient.newCall(request).execute(); assertThat(response.code()).isEqualTo(200); }
Seperti yang kita lihat, defaultClient gagal menyelesaikan panggilan HTTP kerana tamat masa membaca yang melebihi.
Itulah sebabnya kami membuat extendedTimeoutClient, menyesuaikan nilai timeout, dan berjaya melaksanakan permintaan tersebut.
7. Ringkasan
Dalam artikel ini, kami meneroka jangka masa yang berlainan yang dapat kami konfigurasikan untuk OkHttpClient .
Kami juga menerangkan dengan ringkas bila masa tamat sambungan, baca dan tulis digunakan semasa panggilan HTTP.
Selain itu, kami menunjukkan betapa mudahnya mengubah nilai batas waktu tertentu hanya untuk satu permintaan .
Seperti biasa, semua contoh kod boleh didapati di GitHub.