源码分析
打开到目标服务器的连接并继续到下一个拦截器。网络可以用于返回的响应,或者使用条件GET验证缓存的响应。
注释先放在这里了,虽然字都认识,但是基本看不懂。
核心代码就3行,第一行强制类型转换生成realChain, 第二行初始化exchange,realCall中实际负责发起连接和数据传输的是exchange 第三行copy责任链用于
我们来看initExchange到底干了什么
注释是:查找一个新的或合并的连接来承载即将到来的请求和响应。
检查了三个属性,防止其他线程对这个call进行操作
然后我们看到val codec = exchangeFinder.find(client, chain)这一行
查找连接,如果连接正常则返回该连接。如果该进程不健康,则重复该进程,直到找到健康的连接为止。通过死循环去找到健康的连接。
我们先看findConnection构造方法:
注释意思是,优先去复用已有的连接,如果复用不了或者没有连接,最后才去创建一个新连接。(这里还可以继续往细挖掘,看以后填不填坑吧)
然后我们看到isHealthy方法传入doExtensiveHealthChecks参数,也就是chain.request.method != "GET"
// Confirm that the connection is good.
if (candidate.isHealthy(doExtensiveHealthChecks)) {
return candidate
}
Socket 连接被关闭了又或者输入连接被关闭了或者输出连接被关闭了,则是一个不健康的连接 然后如果是http2对连接时间进行校验,下一个是如果连接时间超过10秒且不是get请求返回socket是否健康。(这两个对连接时间校验大家自行研究,我这里理解可能不清晰)
再回到findHealthyConnection方法,如果找到健康的连接则返回,如果没有找到健康的连接,把他从线程池删除,然后继续找健康的连接。
总结
- 这个拦截器主要的作用就是负责从连接池获取健康的连接(判断连接的 Socket 传输通道是否可用),如果在连接池中没有找到符合复用的连接(除了主机地址之外的信息必须要全部匹配,例如 DNS、代理、协议、证书),那么就会使用路由再找一遍(路由的结构是一个代理服务器的地址 + DNS 中的一个 IP 地址),如果还是没有,那么会直接创建一个新的连接对象并进行三次握手,再将这个新的连接对象添加到连接池中,最后将可复用的连接返回回去。