Android OkHttp官方Wiki之Connections

虽然用户只使用URL发起请求时,但是OkHttp会使用URL,Address和Route路由来与服务器进行连接。

URLs

URL统一资源标识符是用来连接HTTP和互联网的最基本的要素。URL除了为网络上的所有东西提供一个通用,分散的命名方案,同时也能指定如何访问网络资源。一个URL的组成成分包括了Scheme方案,Username and Password,Host主机名,Port端口,Path路径,Query查询参数,Fragment片段。

URLs是抽象的:

  • URL可以指定请求是纯文本的(http)或者加密的(https),但是不需要使用哪种加密算法。它们也没有指定如何验证对等的证书(HostnameVerifier)或者哪些证书可以被信任(SSLSocketFactory)。
  • URL没有指定是否应该使用特定的代理服务器或者如何使用该代理服务器进行身份验证。
  • 同时URLs也是具体的:每一个URL标识一个特定的路径(如/square/okhttp)和查询(如q=sharks&lang=en)。每一个Web服务器都有许多URL。

    在OkHttp中使用HttpUrl这个类来表示统一资源表示符Url,可以使用这个类来组合和分解Internet地址。

    public final class HttpUrl
    extends Object

    例如下面的代码会组合并打印一个Google Search的URL:

    
       HttpUrl url = new HttpUrl.Builder()
           .scheme("https")
           .host("www.google.com")
           .addPathSegment("search")
           .addQueryParameter("q", "polar bears")
           .build();
       System.out.println(url);

    打印结果如下:
    https://www.google.com/search?q=polar%20bears

    下面的代码会打印Twitter search URL中人类可读的查询参数:

       HttpUrl url = HttpUrl.parse("https://twitter.com/search?q=cute%20%23puppies&f=images");
       for (int i = 0, size = url.querySize(); i < size; i++) {
         System.out.println(url.queryParameterName(i) + ": " + url.queryParameterValue(i));
       }

    打印结果如下:
    q: cute #puppies
    f: images

    除了可以将组成成分组合成URL和将URL分解为个组成成分,HttpUrl这个类还可以实现对URL的爬取解析,例如通过单击指定页面上的一个相对链接,将获得什么地址。例如下面的代码:

      HttpUrl base = HttpUrl.parse("https://www.youtube.com/user/WatchTheDaily/videos");
       HttpUrl link = base.resolve("../../watch?v=cbP2N1BQdYc");
       System.out.println(link);

    打印结果如下:
    https://www.youtube.com/watch?v=cbP2N1BQdYc

    Addresses

    一个地址指定Web服务器(例如github.com)以及连接到该服务器所需的所有静态配置:端口数量,HTTPS设置和首选的网络协议(例如HTTP/2或者SPDY)。

    共享相同地址的url可能共享相同的TCP套接字连接。共享连接具有显著的性能优势: 更低的延迟,更高的吞吐量(得益于TCP慢启动)和保护电池。OKHttp使用ConnectionPool来自动复用HTTP/1.X连接和多路复用HTTP/2和SPDY连接。

    在OkHttp中,地址的某些字段来自于URL(scheme,主机名,端口),其余部分则来自OkHttpClient。

    在OkHttp中Address类如下:

    public final class Address
    extends Object

    Address是一个连接到服务器的规范。对于一些简单的连接,这是服务器的主机名和端口。如果请求一个显式的代理(或者没有明确请求代理),那么这也包括代理信息。对于安全连接,地址还包括SSL套接字工厂,主机名验证器和证书pinner。

    Routes

    路由提供了必要的动态信息,以便连接到网络Web服务器。这包含了尝试连接的特定IP低着(通过DNS查询发现),要使用的确切代理服务器(如果使用了ProxySelector),以及要协商的TLS版本(用于HTTPS连接)。
    对于一个地址来说可能有很多网络路径可以到达。例如,托管在多个数据中心中的Web服务器可能会在其DNS响应中产生多个不同的IP地址。

    Connections

    当使用OkHttp来请求一个URL地址时,会做如下步骤:

  • 1.OkHttp使用URL和已经配置好的OkHttpClient来创建一个地址。这个地址指定了我们如何连接到Web服务器。
  • 2.OkHttp尝试从连接池中检索该地址的连接。
  • 3.如果在连接池中没有检索到该地址的连接,那么OkHttp将尝试选择一条路由路径,即发出一个DNS请求来获取服务器的IP地址。然后在必要时选择一个TLS版本和代理服务器。
  • 4.如果这是一条新的路由,OkHttp将通过构建一个直接的套接字连接,一个TLS隧道(用于HTTP代理上的HTTPS)或者直接的TLS连接来连接。根据需要,OkHttp会进行TLS握手。
  • 5.跟服务器连接完成后,OkHttp会发送HTTP请求并读取响应结果。
  • 如果连接存在问题,OkHttp将选择另一条路由路径并再次尝试。当服务器地址的子集不可到达时,OkHttp允许恢复。这对于连接失败或者TLS版本不支持时,这很有用。
    一旦接收到响应结果,此次连接将被返回到连接池中以便在将来的请求中可以重用它。当连接池中的某个连接在一段时间内不使用时,该连接便从连接池中被丢弃出去。

    在OkHttp中,Connection是一个接口:

    public interface Connection

    Connection是一个HTTP,HTTPS或者HTTPS+HTTP/2连接的套接字和流,可以用于多个HTTP请求/响应交换。连接可以直接连接到源服务器或者通过代理连接。这个类的典型实例是由HTTP客户机自动创建,连接和执行的。应用程序可以使用这个类作为连接池的成员来监视HTTP连接。

    参考资料:
    https://github.com/square/okhttp/wiki/Connections
    http://square.github.io/okhttp/3.x/okhttp/okhttp3/HttpUrl.html
    http://square.github.io/okhttp/3.x/okhttp/okhttp3/Address.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值