The HTTP client’s job is to accept your request and produce its response. This is simple in theory but it gets tricky in practice.
Http client 的作用就是接收你的请求然后提供对此的响应,这从原理来说很简单,但是实践起来却比较棘手.
Requests(请求)
Each HTTP request contains a URL, a method (like GET
or POST
), and a list of headers. Requests may also contain a body: a data stream of a specific content type.
每个 Http request 都包含一个 URL,一个 method(诸如 GET
或者 POST
之类),以及一系列的 headers.有的请求或许还包含 reqeustBody(针对不同的 content type 有不同的数据流格式)
Responses(响应)
The response answers the request with a code (like 200 for success or 404 for not found), headers, and its own optional body.
response 是对 request 的应答,包含一个 code(比如 200 代表请求成功,或者 404 代表请求资源未找到),响应头 headers,以及可选的 response body 内容.
Rewriting Requests(重写请求)
When you provide OkHttp with an HTTP request, you’re describing the request at a high-level: “fetch me this URL with these headers.” For correctness and efficiency, OkHttp rewrites your request before transmitting it.
当你使用 OkHttp 发起一个 HTTP request 时,代表你在描述一个高标准的 request: “给我用这些 headers 搞定这个 URL” 正确且高效,(为了达到这样的效果)OkHttp 将会在真正发起这个 request 前重写它
(注:王婆卖瓜 orz)
OkHttp may add headers that are absent from the original request, including Content-Length
, Transfer-Encoding
, User-Agent
, Host
, Connection
, and Content-Type
. It will add an Accept-Encoding
header for transparent response compression unless the header is already present. If you’ve got cookies, OkHttp will add a Cookie
header with them.
OkHttp 会额外添加一些原始 request 中缺失的 headers,包括 Content-Length
, Transfer-Encoding
, User-Agent
, Host
, Connection
, 以及 Content-Type
.还会添加一个叫 Accept-Encoding
的 header 用于透明压缩响应内容,除非这个 requestr 之前就已经指定了这个 header.如果你获得了 cookies,那么 OkHttp 还会添加一个 Cookie
的 header,内容就是你获得的这些 cookies.(注:这里应该是指从上下文环境中拿到的 cookies,比如我刚刚用 OKhttp 发起一次请求并正确响应,那从这个响应里面是能知道 cookies 内容的,下一次请求就能用上)
Some requests will have a cached response. When this cached response isn’t fresh, OkHttp can do a conditional GET to download an updated response if it’s newer than what’s cached. This requires headers like If-Modified-Since
and If-None-Match
to be added.
有些请求或许会得到一份缓存过的响应,当这些缓存过的响应不刷新,而且未缓存的响应内容比缓存过的要新的话,OkHttp 将会进行一次 有条件的 下载更新响应内容.当然,这个功能需要添加 If-Modified-Since
或者 If-None-Match
这类的 header 才能生效(注:这里是指遇到这种场景 OKhttp 会自动添加 If-Modified-Since
或者 If-None-Match
来进行处理,还是说需要手动添加 If-Modified-Since
或者 If-None-Match
这样的 header,OKHttp 才会做这样的处理,我暂时还不敢确认,后续尝试过来再来落实,或许有已经确认过的大佬在留言告知)
Rewriting Responses(重写响应)
If transparent compression was used, OkHttp will drop the corresponding response headers Content-Encoding
and Content-Length
because they don’t apply to the decompressed response body.
如果透明压缩规则被使用(注:见前文),OKHttp 就会丢弃掉响应中的 Content-Encoding
and Content-Length
这两个 headers,因为他们无法正确反映解压过的响应内容(注:偏小)
If a conditional GET was successful, responses from the network and cache are merged as directed by the spec.
如果一个有条件的 GET 请求被执行,那么 responses 也会按照这个条件规则进行修改.
Follow-up Requests(302 请求)
When your requested URL has moved, the webserver will return a response code like 302
to indicate the document’s new URL. OkHttp will follow the redirect to retrieve a final response.
如果你的 requested URL 被转移,那么 web 服务器就回返回一个响应 code 302
来给你指定一个新的请求地址,OkHttp 将会重新请求这个重定向过的 URL 来获得最终的 response.
If the response issues an authorization challenge, OkHttp will ask the Authenticator
(if one is configured) to satisfy the challenge. If the authenticator supplies a credential, the request is retried with that credential included.
如果 response 需要权限验证,OkHttp 就会向Authenticator
(如果配置过的话) 申请身份凭证来尝试通过验证,如果认证器能够提供凭证的话,OkHttp 就会带着这个凭证尝试重新请求.
Retrying Requests(重试请求)
Sometimes connections fail: either a pooled connection was stale and disconnected, or the webserver itself couldn’t be reached. OkHttp will retry the request with a different route if one is available.
有些时候 connections 会失败:要么是 connections 死了断开,要么是这个服务器节点本身就不可访问了,OkHttp 就会重新尝试请求另外可用的 route 节点.
Calls(调用)
With rewrites, redirects, follow-ups and retries, your simple request may yield many requests and responses. OkHttp uses Call
to model the task of satisfying your request through however many intermediate requests and responses are necessary. Typically this isn’t many! But it’s comforting to know that your code will continue to work if your URLs are redirected or if you failover to an alternate IP address.
因为以上这些情况,一个简单的 request 也许都会产生很多 requests 和 responses,OkHtt 用了 Call
这样一种模型来出色的完成这样需要多个中间请求和响应的工作.典型的手段不多,但是能让你的代码在 URL 被转移或者某个服务器节点发生故障的情况下也能继续正常工作.(注:2333 又开始自夸了/doge)
Calls are executed in one of two ways:
- Synchronous: your thread blocks until the response is readable.
- Asynchronous: you enqueue the request on any thread, and get called back on another thread when the response is readable.
Calls 包含两种方式:
- 同步的: 你的线程将被阻塞直到响应内容可读
- 异步的: 你把请求推到其他线程的队列中,然后当响应内容可读之后在另外的线程上通过回调函数 called back 来获取
Calls can be canceled from any thread. This will fail the call if it hasn’t yet completed! Code that is writing the request body or reading the response body will suffer an IOException
when its call is canceled.
Calls 能在任何线程被取消,如果请求没有完成,被取消后这个请求就将会失败! 如果代码正在执行 request body 写操作或者 response body 读操作,那么此时取消 Calls 的行为将会抛出一个 IOException
异常.
Dispatch(分配)
For synchronous calls, you bring your own thread and are responsible for managing how many simultaneous requests you make. Too many simultaneous connections wastes resources; too few harms latency.
对于同步调用来说,再多同时发起的 requests 你也能在该线程上妥当管理.(要注意的是)太多 simultaneous connections 将会耗费大量的系统资源,而太少的 simultaneous connections 则将会让处理速度变慢,从而带来更高的延迟
For asynchronous calls, Dispatcher
implements policy for maximum simultaneous requests. You can set maximums per-webserver (default is 5), and overall (default is 64).
对于异步调用来说,Dispatcher
可以设置 simultaneous requests 的限制,你可以设置针对单个服务器的并发连接上限(默认是 5),也可以设置整体最大上限(默认是 64)
译:洗澡狂魔,原文 wiki 地址:https://github.com/square/okhttp/wiki/Calls
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于