HTTP客户端的职责是接收请求产出响应,理论上简单但实践中却棘手。
Request
每个HTTP请求包含一个URL,一个方法(像GET或POST),以及请求头列表。Request也可能包含主体:一个特定内容类型的数据流。
Response
Response使用一个code(像200代表成功或404代表没有找到),响应头头列表以及一个可选的主体应答请求。
重写Request
当你提供给OkHttp一个HTTP请求时,你会深度描述这个请求:“fetch me this URL with these headers”。为了正确性和效率,OkHttp会在请求发送前进行重写。
OkHttp可能添加原始请求缺省的头,包括Content-Length,Transfer-Encoding,User-Agent,Host,Connection和Content-Type。除非Accept-Encoding头已经存在,否则它会添加一个支持透明压缩。如果你已得到cookies,OkHttp也会使用它们添加一个Cookie头。
有些请求将会有一个缓存的响应。当缓存的响应不新鲜时,OkHttp可以执行一个有条件的GET来下载一个更新后的响应(如果这个响应比缓存的新鲜)。这个需要添加像If-Modified-Since和If-None-Match这样的请求头。
重写Response
如果使用了透明压缩,OkHttp会丢弃相应的响应头Content-Encoding和Content-Length,因为它们不适用于解压后的响应body。
如果一个有条件的GET执行成功,从网络获取的响应和缓存会按规则进行合并。
跟进Request
当你请求的URL被移动了,服务器会返回一个像302这样的响应码来指出文档的新URL。OkHttp会跟进这个重定向来获取最终的响应。
如果响应发出了授权挑战,OkHttp会询问Authenticator(如果配置了一个)来满足这个挑战。如果authenticator提供了一个证书,请求会带着这个证书重试。
Request重试
有时连接会失败:连接池过期并且失去连接,或者服务器本身不能访问到。如果有一个可用的不同的路由,OkHttp会重试这个请求。
Calls
有了重写,重定向,跟进和重试,你简单的请求可能产生多个请求和响应。OkHttp会使用Call来模化满足请求的任务,然而中间的请求和响应是必要的。通常它们不是很多。但是,知道你的代码在URL重定向后可以继续工作或你可以使用备用IP地址容错是令人欣慰的。
Call执行有两种方式:
- Synchronous:线程会阻塞直到响应可读。
- Asynchronous:在一个线程中入队请求,当你的响应可读时在另外一个线程获取回调。
请求可以从任何线程取消。如果请求还没完成,会使请求失败。当请求取消了,写请求主体和读响应主体的代码会遇到IOException。
请求分发
对于同步调用,你使用的是自己的线程并对管理你同时创建多少请求负责。太多的并发连接浪费资源,太少会造成延迟。
对于异步调用,Dispatcher实现了最大并发请求的策略。你可以设置每个服务器最大值(默认是5)和所有最大值(默认是64)。
原文链接:
https://github.com/square/okhttp/wiki/Calls
OkHttp官方文档系列文章: