Okhttp学习

okhttp相关概念

网络七层模型 TCP五层模型

Tcp 三次握手 四次挥手
Tcp - ip协议
Socket
Http协议
Https
Dns解析

Okhttp源码相关概念

建造者 (自定义属性)
ReCall
分发器
拦截器
连接池

如何去进行网络请求的。

分发器 : 三个队列 和 线程池 。(数据结构 和 工作流程 ) (线程池的如何工作)

拦截器:责任链模式 (每个拦截器是 干什么的?)
连接池

网络相关概念

Tcp 五层模型 : 应用层(HTTP) 传输层(TCP,UDP) 网络层(IP) 数据链路层 物理地址层
OSI七层模式: 应用层分为 应用层 会话层 表示层

Tcp 三次握手:
客户端 发送一个请求申请 + 一个随机数 给 服务器
服务器 接收到 后 发送一个收到请求 + 随机数+1 给客户端
客户端 接受到 后 发送一个收到回复 + 随机数再加1 服务器 网络正式链接

Tcp 四次挥手
客户端 发送 结束的 申请 给服务器
服务器 发送 一个收到申请 和 一些必须发送数据 给 客户端 (客户端进入等待关闭状态)
服务器 再发送一个结束 给客户端
客户端 收到后 链接正式关闭

socket (数据传输方式)基于Tcp-ip协议 建立 socket 链接 ,通过socket来进行 数据传输。进程间的通讯(不同机器之间的通讯)

Http 协议: 请求头 请求空行 请求体 请求空行
响应头 响应空行 响应体

Https 是基于 http+ssl,加密,是对 tcp 三次握手的封装 ,连接时 通过 密钥和公钥 和三个随机数进行通信的

Dns 解析 :解析url地址 将域名 转化成ip地址 和相应 资源地址

Okhttp特点

支持HTTP/2 并允许对同一主机的所有请求共享一个套接字。(http1.0 无法对已经正在使用 的)
支持HTTP/2 则通过连接池,减少请求延迟。
默认请求 Gzip 压缩数据
响应缓存,避免了重复请求网络(强缓存,协商缓存)http协议定义

Okhttp流程

OkhttpClientBuild — OkhttpClient --Request—Call(RealCall)—execute 和enqueue方法------Dispatcher–Interceptor —Response

先通过建造者 构建相应网络请求的参数。得到OkhttpClient 。
Request 类 来确定 请求头信息。
OkhttpClient+Request 封装 Call (请求Call)
Call 调用 enqueue 和execute 进行同步或者异步请求
通过分发器 对任务进行 分发 线程分配
通过拦截器 对任务进行 网络请求

http请求过程是怎么样的?

  1. 域名----Dns解析 —获取 ip
  2. 建立tcp连接 (实质socket连接 得到socket对象)
  3. 用socket去发Http报文给服务器的到 Response(响应体)

分发器

重要 属性和类
Dispatcher
AsyncCall
runningAsyncCall
readyAsyncCall
runningSyncCall
线程池

异步请求工作流程

Created with Raphaël 2.3.0 AsyncCall Dispatcher 如何决定将请求放入ready还是running runningAsyncCall ThreadPool protrolCalls readyAsyncCall 获取符合条件Call yes no yes

问题1:请求进来,如何解决将请求放入ready还是running队列
问题2:如何将ready队列放入running队列?
问题3:线程池是如何工作的?

源码解析:
一个RealCall只能 调用一次 enqueue方法
可以监听请求过曾(Dns解析 ,结束,开始连接)
分发器(new AsyncCall(回调接口))

Dispatcher 有三个队列
readyAsyncCalls runningAsyncCalls runningSyncCalls
数据结构:ArrayDeque (循环数组形成的双端队列)作为栈比Stack 快,作为双端队列比LinkedList快。

问题1 :请求进来 进行dns解析 全部 加入到 ready队列 ,然后再ready队列中一个一个取,当runningAsyncCalls个数小于64并且 callsPerHost同一域名的请求不大于5时,将该元素移至 running队列中。并添加到线程池中。

问题2:执行完一次任务的时候 ,将任务在running队列移除,然后再进行问题1的操作。

问题3:无等待,最大并发的。

executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
          new SynchronousQueue<>(), Util.threadFactory("OkHttp Dispatcher", false));

核心线程为0,最大线程为int的最大值 ,空闲事件为60s 阻塞队列为SynchronousQueue。所以时无等待最大并发。(通过三个队列来控制的。)

线程池的执行原理

线程进来 —先判断是否小于最大核心线程数—等于进入----阻塞队列 —是否满了—判断是否小于最大线程数—是---reject 拒绝策略。
除了阻塞队列 其他都会开线程。

SynchronousQueue ,ArrayBlockingQueue,LinkedBlockingQueue

ArrayBlockingQueue,LinkedBlockingQueue 数组和链表形成阻塞队列

SynchronousQueue 是无容量的阻塞队列。

阻塞队列满了 后 会判断是否小于最大线程数,小于的话会开一个新的线程。

SynchronousQueue 由于容量为0,所以会一直开。(从而达到高并发的效果)

拦截器责任链设计模式

重试重定向拦截器 重试重定向
桥接拦截器 请求头(必要的Host,gzip,contentType,cookies等)
缓存拦截器 缓存是否可用
连接拦截器 根据请求获取socket流
请求服务器拦截器 通过socket发送服务器得到response

自定义拦截器
请求前
网络请求前

socket代理
socks代理和http普通代理与隧道代理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值