您的位置:首页 > 理论基础 > 计算机网络

第三方开源库OKHttp-整体架构和源码分析

2018-03-31 13:20 417 查看
1. HTTP状态码

1xx: Infomational (信息状态码) ,接收的请求正在处理

2xx: Succeed(成功),请求正常处理完毕,如 200

3xx: Redirection(重定向),需要进行附加操作,一般是没有响应数据返回的,如 304(Not,modified)307 (重定向)

4xx: Client Error (客户端的错误),服务器无法处理请求,如 404

5xx: Server Error (服务端的错误),服务器处理请求出错,如 500

2.Http 和 Https 的区别:

Https = Http + 加密 + 验证 + 完整

端口:Http (80) Https (443)

Http 的缺点:

2.1 数据是没有加密传输,可能遭遇窃听

2.2 不验证通信方的身份,可能会遭遇伪装

2.3 无法验证报文的完整性,可能会遭遇篡改

TLS/SSL 协议

加密:对称加密(AES,DES) + 非对称加密 (RSA,DSA)

证书:要钱(便宜),建立连接的速度会拖慢,TCP 3 次握手,8 次握手





3. Http 1.x 和 Http 2.0 的区别

3.1 Http 2.0 采用二进制格式而非文本格式

3.2 Http 2.0 支持完全的多路复用

3.3 Http 2.0 使用报头压缩,降低开销

3.4 Http 2.0 让服务器将响应主动推送给客户端,(带内容推送,不带内容推送的通知)



4. 异步和同步

跟线程没什么关系,打电话

同步:打电话 -> 处理(没挂断) -> 反馈

异步:打电话 -> 处理(挂断)-> 打回来

5. 整体架构和源码分析

5.1 自己如果要写一个框架你要怎么处理

1. 网络是耗时,开线程,new Thread() ? 线程池

2. 处理网络,HttpUrlConnection(简单) 或者 输入流+Socket(麻烦)

3. 网络请求头信息处理,缓存的处理,文件格式上次的方式(表单提交,拼格式)

4. 路由的一些操作,Http 2.0 复用 等等

5.2 OkHttp 大致内容 Okio,Socket

okio:原生的JavaIO + 自定义封装 ,其实就是对于 io 的封装

Socket 连接

拦截器

走一下大致流程

看下使用

OkHttpClient okHttpClient = new OkHttpClient();
// 307    Location:https://www.baidu.com
//  1. 构建一个请求 ,url,端口,请求头的一些参数,表单提交(contentType,contentLength)
Request request = new Request.Builder()
//将String的url转换成HttpUrl
.url("http://www.baidu.com").
build();
//  2. 把 Request 封装转成一个 RealCall
Call call = okHttpClient.newCall(request);
// 3. enqueue 队列处理 执行
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {

}

@Override
public void onResponse(Call call, Response response) throws IOException {
String result = response.body().string();
Log.e("TAG",result);
}
});
}


* Call call = okHttpClient.newCall(request);源码分析*

@Override public Call newCall(Request request) {
//实际返回的RealCall对象
return RealCall.newRealCall(this, request, false /* for web socket */);
}


static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {

RealCall call = new RealCall(client,
c530
originalRequest, forWebSocket);
call.eventListener = client.eventListenerFactory().create(call);
//实际返回的是RealCall对象
return call;


}



* call.enqueue(new Callback())源码分析*

@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
// client.dispatcher()线程池  参数实际封装成AsyncCall对象
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}


AsyncCall源码分析

//NamedRunnable 实际是继承于Runnable方法,则会重写RUnnable中的抽象方法execute
final class AsyncCall extends NamedRunnable {
private final Callback responseCallback;

AsyncCall(Callback responseCallback) {
super("OkHttp %s", redactedUrl());
this.responseCallback = responseCallback;
}
}


client.dispatcher().enqueue(new AsyncCall(responseCallback));中的enqueue源码分析

synchronized void enqueue(AsyncCall call) {
//如果正在运行的队列小于64  正在运行的host小于5
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
//加入到正在运行的队列中
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
//加入到准备的队列中
readyAsyncCalls.add(call);
}
}


* executorService().execute(call);最终执行的是AsyncCall中的execute方法*

@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 {
eventListener.callFailed(RealCall.this, e);
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}


剩下的下一篇文章再分析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: