首先来看okhttp的使用
// 网络请求客户端,同时还有上传下载文件,gzip压缩等功能
OkHttpClient client = new OkHttpClient()
// 构建请求
Request request = new Request.Builder().url(url).build();
// 同步请求
Response response = client.newCall(request).execute();
// 异步请求
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) {
if(callback != null) callback.onResonse(null);
return;
}
callback.onResonse(response);
}
});
1、首先看得到OkhttpClient,builder初始化一些设置
public Builder() {
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
connectionSpecs = DEFAULT_CONNECTION_SPECS;
proxySelector = ProxySelector.getDefault();
cookieJar = CookieJar.NO_COOKIES;
socketFactory = SocketFactory.getDefault();
hostnameVerifier = OkHostnameVerifier.INSTANCE;
certificatePinner = CertificatePinner.DEFAULT;
proxyAuthenticator = Authenticator.NONE;
authenticator = Authenticator.NONE;
connectionPool = new ConnectionPool();
dns = Dns.SYSTEM;
followSslRedirects = true;
followRedirects = true;
retryOnConnectionFailure = true;
connectTimeout = 10_000;
readTimeout = 10_000;
writeTimeout = 10_000;
}
2、调用newcall方法
@Override public Call newCall(Request request) {
return new RealCall(this, request, false /* for web socket */);
}
/**
* Uses {@code request} to connect a new web socket.
*/
@Override public WebSocket newWebSocket(Request request, WebSocketListener listener) {
RealWebSocket webSocket = new RealWebSocket(request, listener, new SecureRandom());
webSocket.connect(this);
return webSocket;
}
可以看出支持WebSocket连接请求
3、excute方法回调
void finished(RealCall call) {
finished(runningSyncCalls, call, false);
}
private void finished(Deque calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
if (promoteCalls) promoteCalls();
runningCallsCount = runningCallsCount();
idleCallback = this.idleCallback;
}
if (runningCallsCount == 0 && idleCallback != null) {
idleCallback.run();
}
}
在队列里取出call,然后执行run,源码如下
@Override protected void execute() {
boolean signalledCallback = false;
try {
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
signalledCallback = true;
responseCallback.onResponse(RealCall.this, response);
}
} catch (IOException e) {
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
} else {
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}
4、连接和连接管理以及连接拦截器
首先连接拦截器
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}
其中有重定向重试连接,缓存连接,缓存连接这里要说的是在连接缓存池中看是否有正在连接的连接。
RealConnection 连接类:
1、最开始的连接,新建连接,新建连接需要首先查找一个合适的路径,然后在该路径上实例化一个新的connection对象
2、从连接池中复用连接,其实就是从维护的队列中找到合适的连接并返回,查找的依据就是Address对象
public void connect(int connectTimeout, int readTimeout, int writeTimeout,
List connectionSpecs, boolean connectionRetryEnabled)
//https连接
/**
* Does all the work to build an HTTPS connection over a proxy tunnel. The catch here is that a
* proxy server can issue an auth challenge and then close the connection.
*/
private void buildTunneledConnection(int connectTimeout, int readTimeout, int writeTimeout,
ConnectionSpecSelector connectionSpecSelector) throws IOException {
HTTPS是HTTP over SSL/TLS,HTTP是应用层协议,TCP是传输层协议,在应用层和传输层之间,增加了一个安全套接层SSL/TLS
ConnectionPool 连接池管理
public ConnectionPool() {this(5, 5, TimeUnit.MINUTES);}
双端队列deque,设置一个有最大五个连接,连接时长为5分钟的连接池,根据address来判断,如果,连接池中有这个长连接直接复用。