本文為譯文,原文在:https://futurestud.io/tutorials/retrofit-2-customize-network-timeouts
okHTTPclient 配置超時(shí)時(shí)間
默認(rèn)情況下,Retrofit 的默認(rèn)超時(shí)時(shí)間如下:
- Connection timeout: 10 秒
- Read timeout: 10 秒
- Write timeout: 10 秒
- Call timeout: 0 秒 (代表沒有超時(shí))
下面我們解釋下各個(gè)超時(shí)時(shí)間分別代表什么含義
如何設(shè)置超時(shí)時(shí)間
你應(yīng)該已經(jīng)了解到,網(wǎng)絡(luò)請求超時(shí)時(shí)間的設(shè)置不是在 Retrofit 里面設(shè)置的,而是通過對 okHTTPclient 的設(shè)置來完成。okHTTPclient 作為 Retrofit 的網(wǎng)絡(luò)層,設(shè)置網(wǎng)絡(luò)超時(shí)時(shí)間的代碼如下所示:
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.callTimeout(2, TimeUnit.MINUTES)
.build();
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("http://10.0.2.2:3000/")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create());
The code above sets the connection timeout to one minute, the read timeout to 30 seconds, and the write timeout to 15 seconds. Of course you don't have to change all three at the same time and can just modify whatever subset you want to modify. Let's look at each timeout in more detail.
以上代碼將 connectionTimeout 設(shè)置為 1 分鐘,readTimeout 設(shè)置為 30秒,writeTimeout 設(shè)置為 15 秒,callTimeout 設(shè)置為 2 分鐘。當(dāng)然如果你不想改變Retrofit 中的某項(xiàng)的默認(rèn)值,可以不必配置他,也就是說你只需要按照自己的需要配置即可。我們來看下這些 timeout 分別代表什么。
Connection Timeout - 連接超時(shí)
connectionTimeout 應(yīng)該是最有意思的一種超時(shí)設(shè)置了。 他指的是從客戶端發(fā)出一個(gè)請求開始到客戶端與服務(wù)器端完成 TCP 的 3 次握手建立連接的這段時(shí)間。換句話說,如果 Retrofit 在指定的時(shí)間內(nèi)無法與服務(wù)器端建立連接,那么 Retrofit 就認(rèn)為這次請求失敗。
比如,當(dāng)你的用戶可能會(huì)在網(wǎng)絡(luò)狀態(tài)不佳的情況下與你的服務(wù)器進(jìn)行通信,那么你需要增大這個(gè)數(shù)字。
Read Timeout - 讀取超時(shí)
讀取超時(shí)(readTimeout)指的是這段時(shí)間區(qū)間:從連接建立成功開始,Retrofit 就會(huì)監(jiān)測每個(gè)字節(jié)的數(shù)據(jù)傳輸?shù)乃俾?。如果其中某自己距離上一字節(jié)傳輸成功的時(shí)間大于指定的 readTimeout 了,Retrofit 就會(huì)認(rèn)為這個(gè)請求是失敗的。這個(gè)時(shí)間計(jì)數(shù)器會(huì)在讀取到每個(gè) byte 之后歸零重新開始計(jì)時(shí)。所以如果你的響應(yīng)當(dāng)中有 120 個(gè) bytes 需要傳輸?shù)娇蛻舳耍總€(gè) byte 的傳輸都需要 5 秒,這種情況下盡管完全傳輸需要 600 秒,但不會(huì)觸發(fā) readTimeout(30 秒)error。
另外,readTimeout 的觸發(fā)不僅限于服務(wù)器端的處理能力,也有可能是由于糟糕的網(wǎng)絡(luò)狀態(tài)引起。
譯者注:注意這個(gè)并不是說在指定的時(shí)間(比如 30 秒)內(nèi)需要把響應(yīng)內(nèi)容完全接收,而是指相鄰的兩個(gè)字節(jié)之間的接收時(shí)間不能超過指定的時(shí)間( 30 秒)。
Write Timeout - 寫入超時(shí)
寫入超時(shí)(writeTimeout)是跟readTimeout 相對應(yīng)的反方向的數(shù)據(jù)傳輸。他檢查的是客戶端向服務(wù)器端發(fā)送數(shù)據(jù)的速率。當(dāng)然,跟 readTimeout的計(jì)時(shí)器類似,每個(gè) byte 發(fā)送成功之后這個(gè)計(jì)時(shí)器都會(huì)被重置。如果某個(gè)byte 的數(shù)據(jù)傳輸時(shí)間超過了配置的寫入超時(shí)時(shí)間,Retrofit 就會(huì)認(rèn)為這個(gè)請求是失敗的。
譯者注:注意這個(gè)并不是說在指定的時(shí)間(比如 15 秒)內(nèi)需要把所有的數(shù)據(jù)都發(fā)送到服務(wù)器端,而是指相鄰的兩個(gè)字節(jié)之間的發(fā)送時(shí)間不能超過指定的時(shí)間(15 秒)。
Call Timeout - 請求超時(shí) [譯者注]
這部分內(nèi)容是從這里看到的: https://square.github.io/okhttp/4.x/okhttp/okhttp3/-ok-http-client/-builder/call-timeout/
The call timeout spans the entire call: resolving DNS, connecting, writing the request body, server processing, and reading the response body. If the call requires redirects or retries all must complete within one timeout period.
Call timeout 的計(jì)時(shí)器橫跨整個(gè)請求,從 DNS 解析,連接建立,發(fā)送數(shù)據(jù)到服務(wù)器,服務(wù)器端處理,然后發(fā)送響應(yīng)到客戶端,直到客戶端完全讀取響應(yīng)內(nèi)容。如果這個(gè)請求需要重定向或重試,這些過程都必須在指定的 callTimeout 時(shí)間區(qū)間內(nèi)完成。如果不能完成 Retrofit 就會(huì)認(rèn)為請求失敗。
這個(gè) callTimeout 的默認(rèn)值為 0 代表不考慮請求的超時(shí)。
譯者注: 當(dāng)你的應(yīng)用內(nèi)需要限定 App 在某個(gè)指定的時(shí)間內(nèi)得到響應(yīng)結(jié)果,如果在指定時(shí)間內(nèi)未能得到就認(rèn)為是超時(shí)的話,那么你應(yīng)該用callTimeout.