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
该类用于管理所有网络请求的连接,对于满足特定条件的连接进行复用。
- 构造函数:
// 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;
}
梦想不是浮躁,而是沉淀和积累