/**
* Bridge between OkHttp's application and network layers. This class exposes high-level application
* layer primitives: connections, requests, responses, and streams.
*
* <p>This class supports {@linkplain #cancel asynchronous canceling}. This is intended to have the
* smallest blast radius possible. If an HTTP/2 stream is active, canceling will cancel that stream
* but not the other streams sharing its connection. But if the TLS handshake is still in progress
* then canceling may break the entire connection.
*/
public final class Transmitter {
private final OkHttpClient client;
private final RealConnectionPool connectionPool;
private final Call call;
private final EventListener eventListener;
private final AsyncTimeout timeout = new AsyncTimeout() {
@Override protected void timedOut() {
cancel();
}
};
}
看注释,这个类是应用层和网络层之间的桥聊。这个类暴露了高水平的应用层的属性,connection等。
这个类支持请求的异步取消。
我们看下取消的逻辑
我们知道新建call是创建的realcall,取消也需要看下realcall的cancel
@Override public void cancel() {
transmitter.cancel();
}
transmitter的cancel
public void cancel() {
Exchange exchangeToCancel;
RealConnection connectionToCancel;
synchronized (connectionPool) {
canceled = true;
exchangeToCancel = exchange;
connectionToCancel = exchangeFinder != null && exchangeFinder.connectingConnection() != null
? exchangeFinder.connectingConnection()
: connection;
}
if (exchangeToCancel != null) {
取消数据交换
exchangeToCancel.cancel();
} else if (connectionToCancel != null) {
取消连接
connectionToCancel.cancel();
}
}
接下来看超时机制
在realCall的execute方法中
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
开始超时计时
transmitter.timeoutEnter();
transmitter.callStart();
try {
client.dispatcher().executed(this);
return getResponseWithInterceptorChain();
} finally {
client.dispatcher().finished(this);
}
}
public void timeoutEnter() {
timeout.enter();
}
我们看下timeout的enter方法
fun enter() {
check(!inQueue) { "Unbalanced enter/exit" }
val timeoutNanos = timeoutNanos()
val hasDeadline = hasDeadline()
if (timeoutNanos == 0L && !hasDeadline) {
return // No timeout and no deadline? Don't bother with the queue.
}
inQueue = true
此处开始计时
scheduleTimeout(this, timeoutNanos, hasDeadline)
}