okhttp——3. 連接池複用

Connection

首先看一下okhttp如何定義連接,Connection接口可略知一二

public interface Connection {
  /** Returns the route used by this connection. */
  Route route();

  /**
   * Returns the socket that this connection is using. Returns an {@linkplain
   * javax.net.ssl.SSLSocket SSL socket} if this connection is HTTPS. If this is an HTTP/2
   * connection the socket may be shared by multiple concurrent calls.
   */
  Socket socket();

  /**
   * Returns the TLS handshake used to establish this connection, or null if the connection is not
   * HTTPS.
   */
  @Nullable Handshake handshake();

  /**
   * Returns the protocol negotiated by this connection, or {@link Protocol#HTTP_1_1} if no protocol
   * has been negotiated. This method returns {@link Protocol#HTTP_1_1} even if the remote peer is
   * using {@link Protocol#HTTP_1_0}.
   */
  Protocol protocol();
}

在okhttp中實現了Connection接口的類是RealConnection, 裏面涉及到了如何建立一次連接。

ConnectionPool

該類用於管理所有網絡請求的連接,對於滿足特定條件的連接進行復用。

  1. 構造函數:
// maxIdleConnections: 單個url最大的連接數 
// keepAliveDuration: 單個連接的有效期  timeUnit: 有效期的時間單位

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);
    }
  }

  // okhttp 使用如下默認值
  public ConnectionPool() {
    this(5, 5, TimeUnit.MINUTES);
  }

ConnectionPool 的構造只會在OkhttpClient的Builder裏面創建一次,其它所有類持有的ConnectionPool都是通過參數傳遞過去的。

重要成員:

// 用於存放連接的雙向隊列
private final Deque<RealConnection> connections = new ArrayDeque<>();

獲取可重用的連接

 /**
   * Returns a recycled connection to {@code address}, or null if no such connection exists. The
   * route is null if the address has not yet been routed.
   */
  @Nullable RealConnection get(Address address, StreamAllocation streamAllocation, Route route) {
    assert (Thread.holdsLock(this));
    for (RealConnection connection : connections) {
      if (connection.isEligible(address, route)) {
        streamAllocation.acquire(connection);
        return connection;
      }
    }
    return null;
  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章