Java--OkHttp解析

当下Android的网络请求框架非OkHttp莫属,现在就来分析下ok的实现,如果有可能的话可以照着其中的一些模式自己实现一下STTP(Simple Text Transfer Protocal),即简单的文本传输协议(不好意思,事实上并没有STTP协议…)

分析代码之前我们可以预设几个问题,我这里比较关心如下细节:

  • 问题1:ok是如何处理从报文流的
  • 问题2:缓存如何实现
  • 问题3:ssl如何实现
  • 问题4:socket如何管理
  • 问题5:ok如何管理连接池

问题2

问题3

问题1中说到在RealConnection中有个connectTls方法,用来进行ssl握手,握手的过程交给了Java的SSLSocket类,但是ok会有一个Handshake类来封装一些SSL的信息,然后会进行校验,当然,校验过程也是JDK实现的(HostnameVerifier),所以这个问题实际上就是和普通的Socket一样,把连接的几次握手细节隐藏了。

问题1

ok是如何处理从报文流的?

Http基于Tcp协议,而Tcp在Java中使用Socket实现,在ok中使用socket的输入输出流处理报文基本围绕RealConnectionHttpCodec展开。

RealConnection

其中RealConnection是ok抽象的连接,连接拥有socket(可以看到代码中有两个Socket,事实上如果连接是基于ssl的,那么使用rawSocket经过包装之后的socket,如果是普通的通道,那么socket就直接等于rawSocket)、输入流(source)和输出流(sink),针对问题5,其他的都是浮云,可以暂时忽略。

两个重要的方法:

1
buildTunneledConnection(connectTimeout, readTimeout,writeTimeout,connectionSpecSelector);

建立有通道的连接,一般来说就是https了

1
buildConnection(connectTimeout, readTimeout, writeTimeout, connectionSpecSelector);

建立普通的连接

两个方法看上去都是在建立连接,但是有点不太一样,普通无通道的连接是直接socket connect即可,而有通道的连接建立是先connect socket,然后在这个socket之上发送建立通道的报文并接受成功的报文之后才算是建立好了连接。

在两个connection建立好之后其实还有一个方法:

1
private void establishProtocol(int readTimeout, int writeTimeout,ConnectionSpecSelector connectionSpecSelector)throws IOException

顾名思义,就是建立或者协商一个协议,这里面会决定使用http1.0还是2.0,需不需要tls(connectTls)等等

HttpCodec

HttpCodec是真正的流操作,这里以Http1Codec(对应http1)为例,这个类有两个重要的方法,没错,就是输出流的写操作和输入流的读操作:

1
public Response.Builder readResponse() throws IOException
1
public void writeRequest(Headers headers, String requestLine) throws IOException

但是等等,这里似乎只有读取或写入头部信息的方法,https建立ssl连接的时候会写入建立连接的请求和接受连接建立成功的返回报文,事实上普通的http也会用这两个方法读取和写入报文。

到这里并没有看到payload的请求返回报文处理,那么真正请求body的地方在哪儿?

其实这里漏了两个方法:

1
Sink createRequestBody(Request request, long contentLength);

根据Http1Codec的原始sink包装一下变成请求的sink输出流

1
ResponseBody openResponseBody(Response response) throws IOException;

同样,根据Http1Codec的原始source包装一下变成返回报文的source流

问题5到这里就分析完毕了~

continue…

参考文档
http://static.blog.piasy.com/2016/07/11/Understand-OkHttp/

http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html