OKHttp源码解析-连接池

本文详细解析了OkHttp的连接池实现,涉及核心类ConnectionPool、Http2Connection等,以及初始化、put、get和clean等操作。初始化时设置最大空闲连接数和保持连接时间。put和get方法用于管理连接,clean则负责定期清理超时或过多的空闲连接。
摘要由CSDN通过智能技术生成

前面分析Retrofit的源码,Retrofit底层使用了OkHttp来做网络请求操作。在介绍ConnectInterceptor时有设计到OkHttp的连接池ConnectionPool。本篇文章将详细介绍其实现。

核心类

OkHttp的连接池主要涉及几个核心类,ConnectionPool.javaRealConnection.javaStreamAllocation.javaInternal.java

  • ConnectionPool.java
    这个类主要负责管理HTTP HTTP/2连接的重用以减少网络延时。它实现了连接重用、清理的的策略。

  • Internal.java
    外部对连接池不直接操作,而是通过这个类来完成。这个类是一个抽象类,只有一个唯一的实现,就在OKHttpClient中。

  • RealConnection.java
    这是真正处理物理连接的类。普通Socket的连接、SSL Socket的连接、IO的读写都是在这个类完成的。

  • StreamAllocation.java
    这个类主要用于处理物理Sokect连接、Streams(逻辑上的Http Request流和Response流)以及Calls(请求数据,包括原始请求以及重定向的请求或者需要证书认证的请求)之间的关系。每个连接有它们自己的分配上限,这决定了每个连接能够承载多少路并发流。HTTP 1.x一次最多有一路流,HTTP/2可以有多路。
    这个类提供了每一个连接以及每个连接里的流的释放的API。
    这个类还可以提供取消异步请求的API。

初始化

连接池的初始化在OKHttpClient的Builder函数里面。

  public static final class Builder {
	  ...
    ConnectionPool connectionPool;
	  ...

    public Builder() {
	  ...
      connectionPool = new ConnectionPool();
	  ...
    }
}

我们知道Java类的初始化顺序

再看下ConnectionPool的构造函数。

  public ConnectionPool() {
    this(5, 5, TimeUnit.MINUTES);
  }
  public ConnectionPool(int maxIdleConnections, long keepAliveDuration, TimeUnit timeUnit) {
    this.maxIdleConnections = maxIdleConnections;
    this.keepAliveDurationNs = timeUnit.toNanos(keepAliveDuration);

    // Put a floor on the keep alive duration, otherwise cleanup will spin loop.
    if (keepAliveDuration <= 0) {
      throw new IllegalArgumentException("keepAliveDuration <= 0: " + keepAliveDuration);
    }
  }

初始化连接池的时候主要传入了2个参数。一个是maxIdleConnections,表示连接池中最大的空闲连接数,最大是5。keepAliveDuration表示空闲连接与服务器保持连接的时间,最大是5分钟。

put

put方法是在StreamAllocation类的findConnection方法里面调用的。findConnection已经在Android-Retrofit源码解析(一)调用流程(下)里分析过了。我们只看下相关的代码。

  private RealConnection findConnection(int connectTimeout, int readTimeout, int writeTimeout,
      int pingIntervalMillis, boolean connectionRetryEnabled) throws IOException {
...
    synchronized (connectionPool) {
      if (canceled) throw new IOException("Canceled");

      if (newRouteSelection) {
      //1. 获取到IP地址的集合,然后根据IP地址去连接池里查找是否有可复用的连接。
        // Now that we have a set of IP addresses, make another attempt at getting a connection from
        // the pool. This could match due to connection coalescing.
        List<Route> routes = routeSelection.getAll();
        for (int i = 0, size = routes.size(); i < size; i++) {
          Route route = routes.get(i);
          Internal.instance.get(connectionPool, address, this, route);
          if (connection != null) {
            foundPooledConnection = true;
            result = connection;
            this.route = route;
            break;
          }
        }
      }

//2-1.如果连接池中没有找到可复用的连接,就创建一个连接
      if (!foundPooledConnection) {
        if (selectedRoute == null) {
          selectedRoute = r
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值