2023年6月28日发(作者:)
Android妙⽤SPDY协议提⾼移动端⽹络请求性能 本⽂旨在提出⼀种提⾼移动端⽹络性能的可⾏⽅案。我们知道⽬前移动端使⽤的⽹络请求协议基本上都是http。⽤的最多的是http/1.1,http/2.0正在逐渐壮⼤,实际上http/2.0是基于google提出的SPDY协议改进⽽来。废话不多说,马上进⼊正题。 关于SPDY协议的详细介绍,请参看 OkHttp完全解析(七)SPDY协议详细介绍 。
关于OkHttp的使⽤及源码分析⽹上相关的资料很多,推荐OkHttp完全解析(⼋)源码解析⼀ 系列⽂章。写的很不错。
从速度上来讲,Http/1.1⽤明⽂传输,⽆需加密验证,速度快;SPDY加⼊了SSL加密握⼿,但是SPDY协议允许⼀个TCP连接复⽤,可以⼀个域名只提供⼀个TCP连接即可完成通信,虽然由于TCP连接复⽤,但是SSL加密握⼿协商过程⼜耗费了⼀定的时间;Http/2.0是Http的加密版本,也是SPDY的升级版本,如果追求⾼安全性,可以选⽤Http/2.0,速度上Http/2.0⽐Http/1.1稍慢。实验证明单纯的将Http/1.1升级到SPDY,速度提升并不明显,原因在于SSL加密层的添加,⼀定程度上拖慢了SPDY协议的效率。本⽂在基于OkHttp开源库的基础上,使⽤SPDY协议,但是强制忽略了SSL握⼿验证过程,强制使⽤SPDY/3.1协议,这样就将SPDY的速度优势发挥出来了。Okhttp的源码量⽐较⼤,逻辑⽐较复杂,我费了不少时间,看懂了⼤致的思路。请在阅读本⽂之前阅读前⾯的OkHttp源码系列⽂章。
针对某个公司的产品,服务器端可以针对域名进⾏配置SPDY协议的使⽤。针对⾃家产品完全可以免去SSL协商过程,直接默认使⽤SPDY协议。关于服务器怎么配置,在此不过多赘述,⾃⾏查阅相关⽂章。
客户端具体实现过程:
下载okHttp源码并进⾏修改,只需修改⼀处即可完成。直接上代码:
中的connect()函数: //当新建连接或者可⽤连接⽆效的时候进⼊此函数 if (connected) throw new IllegalStateException("already connected"); SocketConnector socketConnector = new SocketConnector(this, pool); tedSocket connectedSocket; if (SocketFactory() != null) { // communication } else { // communication. if (!ns(EXT)) { throw new RouteException(new UnknownServiceException( "CLEARTEXT communication not supported: " + connectionSpecs)); } connectedSocket = tCleartext(connectTimeout, readTimeout, route); } socket = ; handshake = ake; //此处已完成协议的协商,protocol变量的值则决定了下⾯所⾛的协议。 protocol = otocol == null ? _1_1 : otocol; /***********加⼊代码**************/ String hostName = l().host(); if ("".equals(hostName) { protocol = _3; } /***********加⼊的代码结束**************/ try { if (protocol == _3 || protocol == _2) { imeout(0); // SPDY timeouts are set per-stream. spdyConnection = new r(t, true, socket).protocol(protocol).build(); nnectionPreface(); } else { httpConnection = new HttpConnection(pool, this, socket); } } catch (IOException e) { throw new RouteException(e); } connected = true; } void connect(int connectTimeout, int readTimeout, int writeTimeout,Request request, List
具体的实现则需要追踪源码。这⾥给出简单的说明。中的connectAndSetOwner函数是每次请求都会进来的函数,注意此处会进⾏判断,当第⼀次建⽴连接时,isConnected返回false,此时会进⼊connect函数,建⽴连接,选择协议,完成连接后,会进⾏isSpdy判断,如果是Spdy协议,那么会将此connnection放⼊连接池中进⾏共享,下次相同域名下的请求到来时,isConnected判断就会为true,则不需要进⾏重复创建连接,实现了连接的共享。⽽若是http/1.1,⼀般不会进⾏连接共享,每次都需要重建连接,效率较低。 void connectAndSetOwner(OkHttpClient client, Object owner, Request request)throws RouteException { setOwner(owner); if (!isConnected()) { List
当然了对于⼤多数应⽤来说,⼀般情况下不会产⽣明显的卡顿,但是效果总不怕好嘛,这⾥只给⼤家提供⼀个⽐较可⾏的思路⽽已。
最近在家⾥闲来⽆事,在看okhttp的源码,确实学到了很多东西,本来想写⼏篇源码分析的⽂章,发现写起来真是繁琐,且⽹上有很多博客解释的很清晰,这⾥就不做重复性⼯作了。
本⽂提供的思路⼏乎只⽤⼀⾏代码就能实现,不过很遗憾,okhttp框架并不能直接设置想要使⽤的协议,没有暴露接⼝给我们,所以我们只能把源码下载下来,在进⾏打jar包啦。
这是我第⼀次写博客,很多地⽅没注意到,看到的请见谅,关于OkHttp这个开源库,我强烈推荐,亲⾃实践了它失败重连等功能,有任何相关问题,欢迎留⾔交流。
发布者:admin,转转请注明出处:http://www.yc00.com/news/1687954699a60551.html
评论列表(0条)