Http请求开始到response流程
接上篇文章,URL的openURLConnection主要是用于生成一个HttpUrlConncetionImpl对象并返回给我们。这里并不会产生网络请求,网络请求核心在于我们调用connect方法或者getResponse系列方法时候,才会真正去产生Http请求。
下图为从http请求开始到拿到响应数据的整个framework层框架图。
- 总结一下:
- 对于一个URL,首先将其解析,然后根据网络请求的协议等各种配置,返回对应的HttpURLConnection的实例对象,用于代理后续的操作。
- 接下来我们调用connect方法进行网络连接,httpURLConnectionImpl会生成一个HttpEngine对象,该对象作为http引擎,负责当前这次请求的处理。生成的HttpEngine对象会从现有的HttpEngine进行拷贝生成。
- httpEngine中维护了一个连接池,从连接池中查找是否有符合条件的已经和目标地址建立过连接的RealConnection对象,如果可以用则返回,否则新建立一个RealConnection对象。
- 对于新建立的RealConnection对象,需要和服务建立连接,RealConnection会创建一个Socket对象,socket里建立一个文件FD用于后续的网络连接,接着调用JNI方法建立连接。
- HttpEngine中定义了两个对象,BufferSink和BufferSource,BufferSink主要用于存储需要发送给服务的数据,包含请求头和请求体。BufferSource用于接收来自服务的响应数据。
- Socket建立好连接后,HttpEngine会先将请求头和请求体写入到BufferSink中,然后发送给服务
- BufferSource会等到服务响应,然后取出里边的数据解析为Response对象。
- Response对象会保存到当前的HttpEngine中,后续获取响应时候直接返回该对象。
关于HttpEngine
HttpEngine对于每个请求都会生成一个HttpEngine对象,但是其生成方式是copy当前已有的HttpEngine,clone出来的。内部使用的HttpStream和Response单独维护。对于连接核心则是优先从连接池中获取。
架构如下:
HttpEngine主要负责的是对外暴露给调用方,方便其针对每个请求进行单独的控制。RealConnection则是维护在连接池中的对象,每个RealConnection都会维护一个Socket连接。
超时时间怎么理解
- 对于connectTimeout
字面意思为连接超时,这个是在Socket和服务建立连接时候的超时时间,由JNI控制完成。
- readTimeout和writeTimeout
这两个是在Https请求中,tls连接中设置的,后续我们会分析https请求时候会讲到,对于普通的http请求,这两个超时时间是没有实际作用的。
如何复用连接的?
总结:
- Http连接的复用针对的是相同协议,相同域名下的相同端口的连接就可以直接复用
- 对于没有可以复用的连接,那么会新建立一个放入到连接池中
- 对于连接池中放入第一个连接时候,会开始异步线程进行不定时的回收超时的连接Socket
需要注意的是:请求结束后,连接并不是马上就会close
下篇文章讲解后续遗留问题
- https请求的具体流程,tls认证
- 读和写的超时时间的理解