美文网首页
OkHttp探索之深入(基本概览)

OkHttp探索之深入(基本概览)

作者: CodeJava | 来源:发表于2021-08-11 04:58 被阅读0次

    前言:

         OkHttp 是 Android 经典的网络架构

    工程比较大涉及知识点比较多,持续更新

    相关
         Okhttp GitHub地址 https://github.com/square/okhttp
    网络知识
         Http协议
         Http1.0
         Http1.1
         Http2.0
         Spdy
    架构设计之设计模式
         外观模式
         责任链模式
         建造者模式
         观察者模式
         享元模式
         策略模式
    池相关
         连接池
         线程池

    网络连接的过程。
    http://www.baidu.com 或者 https://www.baidu.com
    主要流程图

    20200707163658293.jpg

    相关系列文章

    [OKHttp探索之二(网络缓存)] (https://www.jianshu.com/p/efeae28dcb3e)

    OkhttpClient 介绍 都包含哪些信息。

    默认 两个网络协议 Protocol

    public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
      static final List<Protocol> DEFAULT_PROTOCOLS = Util.immutableList(
          Protocol.HTTP_2, Protocol.HTTP_1_1);
        ................................................................
    }
    

    分别是
    Protocol.HTTP_1_1 、 Protocol.HTTP_2
    参考HTTP1.1 和 HTTP2.0的区别

    默认 两个连接规则 ConnectionSpec

    连接到尽可能多的主机。(连通性)

         想要连接更多服务器,得知道得多 (新的旧的都有) 所以要包含旧的TLS版本、以及设计不足的密码套件

    连接的安全性。(安全性)

         想要 更安全性, 得要有最新 TLS版本和最强密码套件。

    ConnectionSpec 用于 指定 传输HTTP流量的socket连接的配置
    协商安全连接时的
    1. TLS版本
    2. 密码套件

     static final List<ConnectionSpec> DEFAULT_CONNECTION_SPECS = Util.immutableList(
          ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT);
    

    具体的安全性与连接性决策由ConnectionSpec实现。OkHttp包括四个内置连接规格:
    前两个是默认配置
    MODERN_TLS   即 modern TLS 现代,最新的,时髦的,流行的,时新的TLS配置.
    这样可以在大多数客户端平台上运行,并可连接到大多数服务器。
    包含这2种版本(TLS 1.3、TLS 1.2)
    要包含 被批准的、经过认可的密码套件

    密码套件 ([cipher suites]
    采用 approved_cipher_suites (被批准的经过认可的密码套件)

    CLEARTEXT     URL的未加密、未经验证的连接 一般指 是用于http://开头的。
    ** ----------------------------------------------------------------------------------------------------**
    RESTRICTED_TLS
    A secure TLS connection that requires a recent client platform and a recent server.
    一种受保护的连接 用于时间上最近用过的的客户端, 时间上最近的服务器。
    包含这2种版本(TLS 1.3、TLS 1.2)
    受限制的,保密的,未完全开放的密码套件

    密码套件 ([cipher suites]
    restricted_cipher_suites (受限制的,保密的,未完全开放的密码套件)

    COMPATIBLE_TLS
    一种向后兼容的回退配置,可在过时的客户端平台上工作,并且可以连接到过时的服务器。如果可能,请选择升级您的客户端平台或服务器而不是使用此配置。
    包含这三种版本(TLS 1.3、TLS 1.2、 TLS 1.1、 TLS 1.0)
    密码套件 ([cipher suites]
    采用 approved_cipher_suites (被批准的经过认可的密码套件)
    密码套件 常用的 RSA 和 ECDHE

    RSA 是比较传统的密钥交换算法,它不具备前向安全的性质,因此现在很少服务器使用的。
    ECDHE 算法具有前向安全,所以被广泛使用。

    OkHttpClient有一个内部类的实现 Internal

    一个抽象类,在OkHttpClient中静态代码块中初始化。

    1.添加Header信息

    2.确定连接池 ConnectionPool

    3.equalsNonHost 检查两个Address是否是同可以复用

    dns相同否,代理相同否。连接模式相同否,代理相同否等,锁定证书相同否,协议相同否,端口相同否、代理验证者等

    4. code

    responseBuilder.code

    5. apply

    ConnectionSpec tlsConfiguration tlsConfiguration.apply(sslSocket, isFallback);

    6. Call newWebSocketCall(OkHttpClient client, Request originalRequest)

    RealCall.newRealCall(client, originalRequest, true);

    7. initExchange

    responseBuilder.initExchange(exchange);

    8. Exchange change

    response.exchange;

    中判断两个地址 Address
    当  1、Connection 已经分配的数量超过分配限制
         2、被标记为不能再分配

    则直接返回 false,

    否则调用 equalsNonHost,
    boolean equalsNonHost(Address that) {
        return this.dns.equals(that.dns)
            && this.proxyAuthenticator.equals(that.proxyAuthenticator)
            && this.protocols.equals(that.protocols)
            && this.connectionSpecs.equals(that.connectionSpecs)
            && this.proxySelector.equals(that.proxySelector)
            && equal(this.proxy, that.proxy)
            && equal(this.sslSocketFactory, that.sslSocketFactory)
            && equal(this.hostnameVerifier, that.hostnameVerifier)
            && equal(this.certificatePinner, that.certificatePinner)
            && this.url().port() == that.url().port();
    }
    

    OkHttpClient.Builder 外观模式加建造者模式

    看看都包含什么 这几个即使OkHttpClient的成员变量, 也是建造者构造时所需的配置
    有点多。

    Dispatcher dispatcher;
        异步执行的调度策略
        最大请求数64个 maxRequests = 64;
        连接的最大请求数5个 maxRequestsPerHost = 5;
        异步请求准备队列

        Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();

        异步请求运行中队列

        Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();

        同步请求运行中队列

        Deque<RealCall> runningSyncCalls = new ArrayDeque<>();

        空闲时回调 Runnable idleCallback;
         ExecutorService executorService;

         线程池的执行者服务 主要用于调度线程的开启、关闭
    这是OkHttp中默认创建的线程池执行者服务

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

         boolean isTerminated() 所有的任务都完成了,并且关闭啦
         shutdown() 关闭
         boolean awaitTermination() 处于阻塞状态,直到所有的任务完成,或者超时啦 , 又或者当前的线程发生中断
         invokeAll() 执行所有的任务
         invokeAny() 执行所有的
         execute() 执行线程池的任务

    Proxy proxy;

    两个属性
    1.SocketAddress sa
    2.Type type
    代理的配置 Type有三种类型 direct、http、socks
    direct代表直接连接
    主要有两个方法
    1.SocketAddress address()
    2.Type type()

    List<Protocol> protocols;

    所用协议集合

    List<ConnectionSpec> connectionSpecs;

    连接规格 上面有提 TSL版本和密码套件

    final List<Interceptor> interceptors = new ArrayList();

    拦截器

    final List<Interceptor> networkInterceptors = new ArrayList();

    网络拦截器

    EventListener.Factory eventListenerFactory;

    事件的监听器, 用户调用Http时的监听, 数量,大小,时长等
    callStart 调用的开始
    dnsStart dns解析开始
    dnsEnd dns解析结束
    connectStart 连接的开始 socket connection
    secureConnectStart 受保护的连接开始 TLS connection.
    secureConnectEnd 连接TLS结束
    connectEnd 连接结束 socket
    connectFailed 连接失败
    connectionAcquired 获取连接后调用
    对于单个Call,可以多次调用该函数。例如,如果响应Call#request的是重定向到另一个地址
    connectionReleased 连接释放后调用 connectionAcquired 在这个方法之后调用
    对于单个Call,可以多次调用该函数。例如,如果响应到 Call#request的是重定向到另一个地址。
    requestHeadersStart
    requestHeadersEnd
    requestBodyStart
    requestBodyEnd
    requestFailed
    responseHeadersStart
    responseHeadersEnd
    responseBodyStart
    responseBodyEnd
    responseFailed
    callEnd
    callFailed

    public interface Factory {
        EventListener create(Call call);
      }
    
    ProxySelector proxySelector;

    代理服务器是介于客户端和服务器之间的一台服务区
    设置了代理服务器之后。客户端请求先被送到代理服务器,由代理服务器向真正的Web服务器发送请求
    ProxySelector getDefault 获取默认代理服务
    void setDefault 设置默认代理
    List<Proxy> select(URI uri) 选择代理
    void connectFailed(URI uri, SocketAddress sa, IOException ioe) 连接失败

    CookieJar cookieJar;

    既是一种策略 又时一种持久性存储
    void saveFromResponse(HttpUrl url, List<Cookie> cookies);
    List<Cookie> loadForRequest(HttpUrl url)

    As policy, implementations of this interface are responsible for selecting which cookies to accept and which to reject.
    作为策略,此接口的实现负责选择要接受和拒绝的cookie。
    As persistence, implementations of this interface must also provide storage of cookies. Simple implementations may store cookies in memory; sophisticated ones may use the file system or database to hold accepted cookies.
    作为持久性,该接口的实现还必须提供cookie的存储。简单的实现可以在内存中存储cookie;复杂的用户可以使用文件系统或数据库来保存接受的cookie。

    Cache cache;

    缓存的内容复杂 见另一篇 OkHttpCache
    将HTTP和HTTPS响应缓存到文件系统,以便可以重用它们,从而节省时间和带宽。
    InternalCache internalCache 内部缓存
    DiskLruCache cache
    writeSuccessCount;
    writeAbortCount;
    int networkCount;
    int hitCount;
    int requestCount;
    Cache(File directory, long maxSize)
    Cache(File directory, long maxSize, FileSystem fileSystem)
    String key(HttpUrl url)
    Response get(Request request)
    CacheRequest put(Response response)
    remove(Request request)
    update(Response cached, Response network)
    abortQuietly( DiskLruCache.Editor editor)
    initialize() 初始化
    delete()
    evictAll()
    Iterator<String> urls()
    String next()
    等等 见另一篇 OkHttpCache

    InternalCache internalCache;

    OkHttp的内部缓存接口。应用程序不应该实现这一点
    Response get(Request request)
    CacheRequest put(Response response)
    remove(Request request) 删除所有的缓存
    update(Response cached, Response network) 更新缓存
    trackConditionalCacheHit() 跟踪一个满足缓存条件的GET请求
    trackResponse(CacheStrategy cacheStrategy) 跟踪满足缓存策略CacheStrategy的响应

    SocketFactory socketFactory;

    此类创建套接字Socket。它可能被其他工厂子类化,这些工厂创建套接字的特定子类,从而为添加公共套接字级功能提供通用框架
    单例 非双重锁
    void setDefault(SocketFactory factory)
    Socket createSocket()
    SocketFactory getDefault()

    SSLSocketFactory sslSocketFactory;

    String getSecurityProperty(final String name) 安全的 财产
    String [] getDefaultCipherSuites()
    String [] getSupportedCipherSuites()
    Socket createSocket(Socket s, String host,int port, boolean autoClose)
    Socket createSocket(Socket s, InputStream consumed, boolean autoClose)

    CertificateChainCleaner certificateChainCleaner;

    证书链的清理器
    List<Certificate> clean(List<Certificate> chain, String hostname)
    CertificateChainCleaner get(X509TrustManager trustManager)
    CertificateChainCleaner get(X509Certificate... caCerts)
    X.509 是密码学里公钥证书的格式标准。
    X.509证书里含有公钥、身份信息(比如网络主机名,组织的名称或个体名称等)和签名信息(可以是证书签发机构CA的签名,也可以是自签名)。

    HostnameVerifier hostnameVerifier;

    主机名验证的基本接口
    在握手过程中,验证机制可以回调此接口的实现者,以确定是否应允许此连接

    public boolean verify(String hostname, SSLSession session);
    
    CertificatePinner certificatePinner;

    锁定证书

    约束受信任的证书。固定证书可防止对证书颁发机构的攻击。它还防止通过应用程序用户已知或未知的中间人证书颁发机构进行连接

    锁定证书限制了服务器团队更新TLS证书的能力。通过锁定证书,可以增加操作复杂性,并限制在证书颁发机构之间迁移的能力。如果没有服务器的TLS管理员的许可,不要使用证书固定!

    如果一个应用使用了Certificate Pinning技术,抓包工具 chales 和 fidder 就无法直接来调试/监控应用的网络流量的。

    Authenticator proxyAuthenticator;

    验证者 验证码 验证人 代理验证者

    返回包含凭据的请求,以满足response中的身份验证质询。如果无法满足质询,则返回null。

    路由是尽最大努力的,即使在逻辑上可用时,目前也可能不总是提供路由。当在应用程序拦截器中手动重新使用身份验证器时,例如在实现特定于客户端的重试时,也可能不提供身份验证器。

    Authenticator authenticator;

    验证者

    ConnectionPool connectionPool;

    连接池

    Dns dns;

    域名解析

    boolean followSslRedirects;

    跟随 ssl 重定向

    boolean followRedirects;

    跟随重定向

    boolean retryOnConnectionFailure;

    重新连接故障

    int callTimeout;

    调用超时

    int connectTimeout;

    连接超时

    int readTimeout;

    读取超时

    int writeTimeout;

    写入超时

    int pingInterval;

    Web套接字和HTTP/2 ping间隔(以毫秒为单位)。默认情况下,不会发送ping
    此篇主要是OkHttp的门面类 OkHttpClient的概览。
    其中包含了较多的相关类。 其中网络缓存篇 网络连接池篇逐一介绍。

    RealConnectionPool

    相关文章

      网友评论

          本文标题:OkHttp探索之深入(基本概览)

          本文链接:https://www.haomeiwen.com/subject/kusqbltx.html