雖然用戶只使用URL發起請求時,但是OkHttp會使用URL,Address和Route路由來與服務器進行連接。
URLs
URL統一資源標識符是用來連接HTTP和互聯網的最基本的要素。URL除了爲網絡上的所有東西提供一個通用,分散的命名方案,同時也能指定如何訪問網絡資源。一個URL的組成成分包括了Scheme方案,Username and Password,Host主機名,Port端口,Path路徑,Query查詢參數,Fragment片段。
URLs是抽象的:
同時URLs也是具體的:每一個URL標識一個特定的路徑(如/square/okhttp)和查詢(如q=sharks&lang=en)。每一個Web服務器都有許多URL。
在OkHttp中使用HttpUrl這個類來表示統一資源表示符Url,可以使用這個類來組合和分解Internet地址。
public final class HttpUrl
extends Object
例如下面的代碼會組合並打印一個Google Search的URL:
HttpUrl url = new HttpUrl.Builder()
.scheme("https")
.host("www.google.com")
.addPathSegment("search")
.addQueryParameter("q", "polar bears")
.build();
System.out.println(url);
打印結果如下:
https://www.google.com/search?q=polar%20bears
下面的代碼會打印Twitter search URL中人類可讀的查詢參數:
HttpUrl url = HttpUrl.parse("https://twitter.com/search?q=cute%20%23puppies&f=images");
for (int i = 0, size = url.querySize(); i < size; i++) {
System.out.println(url.queryParameterName(i) + ": " + url.queryParameterValue(i));
}
打印結果如下:
q: cute #puppies
f: images
除了可以將組成成分組合成URL和將URL分解爲個組成成分,HttpUrl這個類還可以實現對URL的爬取解析,例如通過單擊指定頁面上的一個相對鏈接,將獲得什麼地址。例如下面的代碼:
HttpUrl base = HttpUrl.parse("https://www.youtube.com/user/WatchTheDaily/videos");
HttpUrl link = base.resolve("../../watch?v=cbP2N1BQdYc");
System.out.println(link);
打印結果如下:
https://www.youtube.com/watch?v=cbP2N1BQdYc
Addresses
一個地址指定Web服務器(例如github.com)以及連接到該服務器所需的所有靜態配置:端口數量,HTTPS設置和首選的網絡協議(例如HTTP/2或者SPDY)。
共享相同地址的url可能共享相同的TCP套接字連接。共享連接具有顯著的性能優勢: 更低的延遲,更高的吞吐量(得益於TCP慢啓動)和保護電池。OKHttp使用ConnectionPool來自動複用HTTP/1.X連接和多路複用HTTP/2和SPDY連接。
在OkHttp中,地址的某些字段來自於URL(scheme,主機名,端口),其餘部分則來自OkHttpClient。
在OkHttp中Address類如下:
public final class Address
extends Object
Address是一個連接到服務器的規範。對於一些簡單的連接,這是服務器的主機名和端口。如果請求一個顯式的代理(或者沒有明確請求代理),那麼這也包括代理信息。對於安全連接,地址還包括SSL套接字工廠,主機名驗證器和證書pinner。
Routes
路由提供了必要的動態信息,以便連接到網絡Web服務器。這包含了嘗試連接的特定IP低着(通過DNS查詢發現),要使用的確切代理服務器(如果使用了ProxySelector),以及要協商的TLS版本(用於HTTPS連接)。
對於一個地址來說可能有很多網絡路徑可以到達。例如,託管在多個數據中心中的Web服務器可能會在其DNS響應中產生多個不同的IP地址。
Connections
當使用OkHttp來請求一個URL地址時,會做如下步驟:
如果連接存在問題,OkHttp將選擇另一條路由路徑並再次嘗試。當服務器地址的子集不可到達時,OkHttp允許恢復。這對於連接失敗或者TLS版本不支持時,這很有用。
一旦接收到響應結果,此次連接將被返回到連接池中以便在將來的請求中可以重用它。當連接池中的某個連接在一段時間內不使用時,該連接便從連接池中被丟棄出去。
在OkHttp中,Connection是一個接口:
public interface Connection
Connection是一個HTTP,HTTPS或者HTTPS+HTTP/2連接的套接字和流,可以用於多個HTTP請求/響應交換。連接可以直接連接到源服務器或者通過代理連接。這個類的典型實例是由HTTP客戶機自動創建,連接和執行的。應用程序可以使用這個類作爲連接池的成員來監視HTTP連接。
參考資料:
https://github.com/square/okhttp/wiki/Connections
http://square.github.io/okhttp/3.x/okhttp/okhttp3/HttpUrl.html
http://square.github.io/okhttp/3.x/okhttp/okhttp3/Address.html