该文章大致分为以下几个主题.
- 首先我还是会从一个简单的示例引出我们今天的主角Connections(连接)
- Connections之URLs
- Connections之Addresses
- Connections之Routes
一段简单的代码示例
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();
}
}
上面的代码示例在发送一个请求时虽然只提供了一个URL,但是OkHttp底层使用了URL、Address、Route去连接目标服务器。
URL
url(如https://www.jianshu.com/u/593b152ef28a)是HTTP和Internet的基础。除了作为web上的命名方案之外,它们还指定了如何访问web资源。
它们指定调用可以是明文(http)或加密(https),但不指定应该使用哪种加密算法。它们也没有指定如何验证对等方的证书(HostnameVerifier)或哪些证书可以信任(SSLSocketFactory)。
它们没有指定是否应该使用特定的代理服务器或如何使用该代理服务器进行身份验证。
但它也有必须要指明的内容,即每个URL标识一个特定的路径(比如/square/okhttp)和查询(比如?q=sharks&lang=en)。每个web服务器都会承载许多url。
Addresses
地址指定一个web服务器(如github.com)和连接到该服务器所需的所有静态配置:端口号、HTTPS设置和首选网络协议(如HTTP/2或SPDY)。
共享相同地址的url也可以共享相同的底层TCP套接字连接。共享连接具有显著的性能优势:更低的延迟、更高的吞吐量(由于TCP启动缓慢)和节省电池。OkHttp使用自动重用HTTP/1的ConnectionPool。x连接和多路复用HTTP/2和SPDY连接。
在OkHttp中,地址的一些字段来自URL (scheme、主机名、端口),其余字段来自OkHttpClient。
Routes
Routes提供实际连接到web服务器所需的动态信息。
一个Address可能有很多Route。例如,驻留在多个数据中心的web服务器在DNS响应中可能产生多个IP地址。
当我们使用OkHttp请求URL的时候,它执行的基本步骤如下.
- 它使用 URL 并配置OkHttpClient来创建一个Address。这个Address指定了我们将如何连接到web服务器.
- 接着它试图从连接池中检索具有该地址的连接。
- 如果在池中没有找到连接,则选择要尝试的路由。这通常意味着发出DNS请求来获取服务器的IP地址。然后,如果需要,它将选择TLS版本和代理服务器。
如果是新路由,则通过构建直接套接字连接、TLS隧道(用于HTTP代理上的HTTPS)或直接TLS连接进行连接。必要时还会握手。- 它发送HTTP请求并读取响应。
- 如果连接有问题,OkHttp将选择另一条路由并重试。这允许OkHttp在服务器地址的子集不可用时恢复。当池连接过期或不支持尝试的TLS版本时,它也很有用。
- 一旦接收到响应,连接将返回到池中,以便在将来的请求中重用它。在一段时间不活动之后,连接将从池中删除。
网友评论