Android - 剖析OKHttp(4)- 拦截器Connec

2020-11-09  本文已影响0人  杨0612

源码分析基于 3.14.4

ConnectInterceptor作用

主要负责建立或者复用Socket连接;

//ConnectInterceptor类中
  @Override public Response intercept(Chain chain) throws IOException {
    ......
    Exchange exchange = transmitter.newExchange(chain, doExtensiveHealthChecks);//1
    return realChain.proceed(request, transmitter, exchange);//2
  }
//Transmitter类中
 Exchange newExchange(Interceptor.Chain chain, boolean doExtensiveHealthChecks) {
    ......
    ExchangeCodec codec = exchangeFinder.find(client, chain, doExtensiveHealthChecks);//调用下面的函数,查找一个可以使用的Connection
    ......
  }
  
//ExchangeFinder类中  
public ExchangeCodec find(
     ......
     RealConnection resultConnection = findHealthyConnection(connectTimeout, readTimeout,
          writeTimeout, pingIntervalMillis, connectionRetryEnabled, doExtensiveHealthChecks);//最终会调到ExchangeFinder.findConnection
     ......
  }
//ExchangeFinder类中
private RealConnection findConnection(int connectTimeout, int readTimeout, int writeTimeout,
      int pingIntervalMillis, boolean connectionRetryEnabled) throws IOException {
      .......
      if (connectionPool.transmitterAcquirePooledConnection(address, transmitter, null, false)) {//1
          foundPooledConnection = true;
          result = transmitter.connection;
        }
       .......
       if (result != null) {//找到可以复用的连接,则返回
           return result;
       }
        ......
        result = new RealConnection(connectionPool, selectedRoute);//2
        connectingConnection = result;
        ......
        result.connect(connectTimeout, readTimeout, writeTimeout, pingIntervalMillis,
        connectionRetryEnabled, call, eventListener);//3
        ......
        return result;
  }

RealConnection.connect建立连接

//RealConnection类中
public void connect(int connectTimeout, int readTimeout, int writeTimeout,
      int pingIntervalMillis, boolean connectionRetryEnabled, Call call,
      EventListener eventListener) {
    .......
    while (true) {
      try {
        if (route.requiresTunnel()) {//1
          connectTunnel(connectTimeout, readTimeout, writeTimeout, call, eventListener);
          ......
        } else {//2
          connectSocket(connectTimeout, readTimeout, call, eventListener);
        }
        ......
  }
//普通连接的请求行
GET /user HTTP/1.1 
//使用HTTP代理发送HTTPS请求
GET CONNECT www.baidu.com  HTTP/1.1

RealConnection.connectSocket建立Socket连接

  private void connectSocket(int connectTimeout, int readTimeout, Call call,
      EventListener eventListener) throws IOException {
    Proxy proxy = route.proxy();
    Address address = route.address();

    rawSocket = proxy.type() == Proxy.Type.DIRECT || proxy.type() == Proxy.Type.HTTP
        ? address.socketFactory().createSocket()//1
        : new Socket(proxy);//2
    ......
    Platform.get().connectSocket(rawSocket, route.socketAddress(), 
    connectTimeout);//3
 ......
  }

连接池

public final class ConnectionPool {
  final RealConnectionPool delegate;
  public ConnectionPool() {
    this(5, 5, TimeUnit.MINUTES);//1
  }
  public ConnectionPool(int maxIdleConnections, long keepAliveDuration, TimeUnit timeUnit) {
    this.delegate = new RealConnectionPool(maxIdleConnections, keepAliveDuration, timeUnit);
  }
//RealConnectionPool类中
  void put(RealConnection connection) {
    assert (Thread.holdsLock(this));
    if (!cleanupRunning) {
      cleanupRunning = true;
      executor.execute(cleanupRunnable);//1
    }
    connections.add(connection);//2
  }
  1. 清理空闲连接
 //RealConnectionPool类中
  private final Runnable cleanupRunnable = () -> {
    while (true) {
      long waitNanos = cleanup(System.nanoTime());//调用下面的cleanup函数
      if (waitNanos == -1) return;//7
      if (waitNanos > 0) {
        long waitMillis = waitNanos / 1000000L;
        waitNanos -= (waitMillis * 1000000L);
        synchronized (RealConnectionPool.this) {
          try {
            RealConnectionPool.this.wait(waitMillis, (int) waitNanos);//8
          } catch (InterruptedException ignored) {
          }
        }
      }
    }
  };
 
//RealConnectionPool类中
long cleanup(long now) {
    synchronized (this) {
      for (Iterator<RealConnection> i = connections.iterator(); i.hasNext(); ) {//1
        RealConnection connection = i.next();
        if (pruneAndGetAllocationCount(connection, now) > 0) {//判断连接是否使用,每个连接都有一个弱引用计数,当计数大于0,则表示在使用中
          inUseConnectionCount++;
          continue;
        }

        idleConnectionCount++;//空闲连接计数

        long idleDurationNs = now - connection.idleAtNanos;//计算空闲了多久
        if (idleDurationNs > longestIdleDurationNs) {//记录空闲最久的连接
          longestIdleDurationNs = idleDurationNs;
          longestIdleConnection = connection;
        }
      }

      if (longestIdleDurationNs >= this.keepAliveDurationNs
          || idleConnectionCount > this.maxIdleConnections) {//2
        connections.remove(longestIdleConnection);
      } else if (idleConnectionCount > 0) {//3
        return keepAliveDurationNs - longestIdleDurationNs;
      } else if (inUseConnectionCount > 0) {//4
        return keepAliveDurationNs;
      } else {
        cleanupRunning = false;
        return -1;//5
      }
    }
    ```
    closeQuietly(longestIdleConnection.socket());//6
    return 0;//9
  }

总结

以上分析有不对的地方,请指出,互相学习,谢谢哦!

上一篇 下一篇

猜你喜欢

热点阅读