該文章大致分為以下幾個(gè)主題.
- 首先我還是會(huì)從一個(gè)簡(jiǎn)單的示例引出我們今天的主角Connections(連接)
- Connections之URLs
- Connections之Addresses
- Connections之Routes
一段簡(jiǎn)單的代碼示例
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
Call call = client.newCall(request);
try (Response response = call.execute()) {
return response.body().string();
}
}
上面的代碼示例在發(fā)送一個(gè)請(qǐng)求時(shí)雖然只提供了一個(gè)URL葵硕,但是OkHttp底層使用了URL疏叨、Address、Route去連接目標(biāo)服務(wù)器。
URL
url(如http://www.reibang.com/u/593b152ef28a)是HTTP和Internet的基礎(chǔ)。除了作為web上的命名方案之外,它們還指定了如何訪問(wèn)web資源。
它們指定調(diào)用可以是明文(http)或加密(https),但不指定應(yīng)該使用哪種加密算法杂腰。它們也沒(méi)有指定如何驗(yàn)證對(duì)等方的證書(HostnameVerifier)或哪些證書可以信任(SSLSocketFactory)。
它們沒(méi)有指定是否應(yīng)該使用特定的代理服務(wù)器或如何使用該代理服務(wù)器進(jìn)行身份驗(yàn)證椅文。
但它也有必須要指明的內(nèi)容喂很,即每個(gè)URL標(biāo)識(shí)一個(gè)特定的路徑(比如/square/okhttp)和查詢(比如?q=sharks&lang=en)惜颇。每個(gè)web服務(wù)器都會(huì)承載許多url。
Addresses
地址指定一個(gè)web服務(wù)器(如github.com)和連接到該服務(wù)器所需的所有靜態(tài)配置:端口號(hào)少辣、HTTPS設(shè)置和首選網(wǎng)絡(luò)協(xié)議(如HTTP/2或SPDY)凌摄。
共享相同地址的url也可以共享相同的底層TCP套接字連接。共享連接具有顯著的性能優(yōu)勢(shì):更低的延遲漓帅、更高的吞吐量(由于TCP啟動(dòng)緩慢)和節(jié)省電池锨亏。OkHttp使用自動(dòng)重用HTTP/1的ConnectionPool。x連接和多路復(fù)用HTTP/2和SPDY連接忙干。
在OkHttp中器予,地址的一些字段來(lái)自URL (scheme、主機(jī)名捐迫、端口)乾翔,其余字段來(lái)自O(shè)kHttpClient。
Routes
Routes提供實(shí)際連接到web服務(wù)器所需的動(dòng)態(tài)信息施戴。
一個(gè)Address可能有很多Route末融。例如,駐留在多個(gè)數(shù)據(jù)中心的web服務(wù)器在DNS響應(yīng)中可能產(chǎn)生多個(gè)IP地址暇韧。
當(dāng)我們使用OkHttp請(qǐng)求URL的時(shí)候,它執(zhí)行的基本步驟如下.
- 它使用 URL 并配置OkHttpClient來(lái)創(chuàng)建一個(gè)Address浓瞪。這個(gè)Address指定了我們將如何連接到web服務(wù)器.
- 接著它試圖從連接池中檢索具有該地址的連接懈玻。
- 如果在池中沒(méi)有找到連接,則選擇要嘗試的路由乾颁。這通常意味著發(fā)出DNS請(qǐng)求來(lái)獲取服務(wù)器的IP地址涂乌。然后,如果需要英岭,它將選擇TLS版本和代理服務(wù)器湾盒。
如果是新路由,則通過(guò)構(gòu)建直接套接字連接诅妹、TLS隧道(用于HTTP代理上的HTTPS)或直接TLS連接進(jìn)行連接罚勾。必要時(shí)還會(huì)握手。- 它發(fā)送HTTP請(qǐng)求并讀取響應(yīng)吭狡。
- 如果連接有問(wèn)題尖殃,OkHttp將選擇另一條路由并重試。這允許OkHttp在服務(wù)器地址的子集不可用時(shí)恢復(fù)划煮。當(dāng)池連接過(guò)期或不支持嘗試的TLS版本時(shí)送丰,它也很有用。
- 一旦接收到響應(yīng)弛秋,連接將返回到池中器躏,以便在將來(lái)的請(qǐng)求中重用它俐载。在一段時(shí)間不活動(dòng)之后,連接將從池中刪除登失。