轉載請注明出處 http://www.lxweimin.com/p/41a2d6e3204f (作者:韓棟)
本文為譯文,由于譯者水平有限,歡迎拍磚,讀者也可以閱讀原文
【OkHttp3-基本用法,OkHttp3-使用進階(Recipes),OkHttp3-請求器(Calls),OkHttp3-連接(Connections),OkHttp3-攔截器(Interceptor)】
雖然通常你只需要提供一個URL
給OkHttp,OkHttp就可以幫你完成其他事情。但是實際上OkHttp連接服務器需要三個條件:URL
,Address
,Route
。
URLs(統一資源定位符)
提供一個URL
(比如https://github.com/square/okhttp
)讓Http去連接服務器是最基本的工作。還有一種漸漸普遍的文件定位方式稱為URN(同意名稱定位符)
,它是利用一種分散式的命名方案去指定所需要訪問的資源文件。
URLs
是抽象的:
-
URL
可以指定請求的類型是明文(Http
)或者是密文(Https
),但是無法指定使用的是哪個加密算法,也無法指定怎樣去驗證證書(HostnameVerifier
)或者指定哪種證書可以被驗證(SSLSocketFactory
)。 -
URL
無法指定使用哪些代理服務器,以及指定哪些代理服務器進行身份認證。
URL
是具體的:
- 每一個
URL
都可以定義一個指定的路徑(比如/square/okhttp
)以及查詢條件(比如?q=sharks&lang=en
)。每個主機可以擁有多個URL
。
Address(地址)
Address
在OKHttp中是一個對象,它為OkHttp提供靜態配置!
地址指定了一個服務器(比如github.com
)以及連接此服務器所需要的靜態配置:端口號,HTTPS
設置,以及指定的網絡協議(比如HTTP/2
或者SPDY
)。
相同地址的URL
也可以共用相同的底層TCP Socket
連接。共用相同的連接對于性能有很大的提升:更低的延遲,更大的吞吐量(復用連接,由于每個TCP
啟動的都需要較多的準備工作),更少的電能損耗。OkHttp使用一個連接池,來自動復用HTTP/1.x connections
、HTTP/2
、SPDY
連接。
URL為地址提供了一些字段(比如域名、主機名、端口號),其他的字段都來自于OkHttpClient
。
Routes(路由)
Routes
在OKHttp中是一個對象,它為OkHttp提供動態配置!
路由提供了實際連接到服務器所需要的動態配置。比如所指定用來嘗試連接服務器的IP
地址(從DNS
服務商獲得)、連接過程中實際所使用到的代理服務器(如果使用了ProxySelector
),以及使用的是哪個版本的
TLS
協議(當使用Https
協議連接時候需要)。
對于一個地址來說 ,可能存在有很多種路由的方式。比如,當一個服務器被托管在多個數據中心,這時路由從DNS
供應商獲取的響應中就可以獲取到多個IP
地址。
Connections(連接)
當你使用OkHttp去請求一個URL
時,OkHttp為你做了如下事情:
- OkHttp使用一個
URL
以及經過配置的OkHttpClient
去創建一個address
。這個address
表示我們將如何連接服務器。 - OkHttp嘗試從連接池中獲取一個適用于此
address
的Connection
。 - 如果OkHttp沒有找到對應的
Connection
,那么OkHttp就會選擇一條路由去嘗試創建連接。這通常意味著需要向DNS
供應商發送一個請求去獲取這個服務器的IP
地址,以及可能還需要選擇TLS
版本和代理服務器。 - 如果此路由是一條新的路由,它將通過構建一個
Socket
連接,一個TLS
連接(通過Http
代理的Https
),或者直接通過一個TLS
進行連接(它需要TLS
握手)。 - OkHttp發送
Http
請求并讀取響應。
如果在連接的過程中出現問題,那么OkHttp將會選擇其他的路由進行重新連接。這意味著當一個服務器的某一個IP
地址無法訪問時,OkHttp可以嘗試別的IP
地址進行訪問。或者當一個連接池過期或者你嘗試連接的所用的TLS
版本不受服務器支持時,這種重連機制也是非常有用的。
一旦客戶端發來接收到來自服務器的響應,那么這個Connection
將會被放置到連接池中以備于將來新的連接進行復用。Connection
在長期不使用的情況下,將會從這個連接池中被移除。
··