盡管你只提供了URL,OkHttp在規(guī)劃連接服務(wù)器的連接時(shí)使用了三種類(lèi)型:URL,Address和Route。
URLs
URLs是HTTP和網(wǎng)絡(luò)的最基本的。除了作為一個(gè)通用的,網(wǎng)絡(luò)資源的分散命名機(jī)制,它們也規(guī)定了如何訪問(wèn)網(wǎng)絡(luò)資源。
URLs是抽象的:
- 它們規(guī)定了調(diào)用可能是明文(http)或密文(https),但是沒(méi)有規(guī)定應(yīng)該使用哪個(gè)加密算法。也沒(méi)有規(guī)定如何驗(yàn)證對(duì)等的證書(shū)(HostnameVerifier)或者哪個(gè)證書(shū)可被信任(SSLSocketFactory)。
- 它們沒(méi)有規(guī)定是否一個(gè)特定的代理服務(wù)器可以使用或如何認(rèn)證代理服務(wù)器。
它們也是具體的:每一個(gè)URL確定一個(gè)特定路徑(像/square/okhttp)和查詢(像?q=sharks&lang=en)。每個(gè)服務(wù)器有很多URL。
Addresses
Addresses規(guī)定了服務(wù)器(像github.com)和所有連接服務(wù)器需要的靜態(tài)配置:端口號(hào),HTTPS設(shè)置和優(yōu)先網(wǎng)絡(luò)協(xié)議(像HTTP/2或SPDY)。
共享相同address的URLs也可能共享相同的下層TCP socket連接。共享一個(gè)連接有巨大的性能好處:低延遲,高吞吐量(因?yàn)門(mén)CP啟動(dòng)慢)和節(jié)省電源。OkHttp使用ConnectionPool來(lái)自動(dòng)復(fù)用HTTP/1.X連接和多路傳輸HTTP/2和SPDY連接。
在OkHttp中,address的一些字段來(lái)自URL(機(jī)制,主機(jī)名,端口),剩下的來(lái)自O(shè)kHttpClient。
Routes
Routes提供了真正連接到服務(wù)器所需要的動(dòng)態(tài)信息。這是明確的要嘗試的IP地址(通過(guò)DNS查詢發(fā)現(xiàn)),明確的要使用的代理服務(wù)器(如果使用了ProxySelector)以及什么版本的TLS來(lái)協(xié)商(針對(duì)HTTPS連接)。
對(duì)于一個(gè)地址有可能有很多路由,一個(gè)存在多個(gè)數(shù)據(jù)中心的網(wǎng)絡(luò)服務(wù)器可能在它的DNS響應(yīng)中產(chǎn)生多個(gè)IP地址。
Connections
當(dāng)你使用OkHttp請(qǐng)求一個(gè)URL時(shí),下面是它所做的:
- 它使用URL和配置的OkHttpClient來(lái)創(chuàng)建一個(gè)address。這個(gè)address規(guī)定了如何連接到服務(wù)器。
- 它嘗試用這個(gè)address從連接池中獲取一個(gè)連接。
- 如果它沒(méi)有在池中找到一個(gè)連接,它會(huì)選擇一個(gè)route來(lái)嘗試。這通常意味著創(chuàng)建一個(gè)DNS請(qǐng)求來(lái)獲取服務(wù)器的IP地址。如果需要,它之后會(huì)選擇一個(gè)TLS版本和代理服務(wù)器。
- 如果這是一個(gè)新route,它會(huì)通過(guò)構(gòu)建一個(gè)直接的socket連接或一個(gè)TLS隧道(對(duì)于HTTP代理上的HTTPS)或一個(gè)直接的TLS連接來(lái)進(jìn)行連接。如果需要它會(huì)執(zhí)行TLS握手。
- 它發(fā)送HTTP請(qǐng)求然后讀取響應(yīng)。
當(dāng)連接出現(xiàn)問(wèn)題時(shí),OkHttp會(huì)選擇另外一個(gè)route進(jìn)行嘗試。這使得OkHttp可以在服務(wù)器部分地址無(wú)法訪問(wèn)時(shí)恢復(fù)。它同時(shí)對(duì)于當(dāng)連接池過(guò)期或嘗試的TLS版本不支持時(shí)有用。
一旦接收到響應(yīng),連接就會(huì)返回到池中,這樣它可以在之后的請(qǐng)求復(fù)用。連接空閑一段時(shí)間會(huì)從池中移除。
原文鏈接:
https://github.com/square/okhttp/wiki/Connections
OkHttp官方文檔系列文章: