OKHttp源码解析sz

2024-01-22 17:32
文章标签 源码 解析 okhttp sz

本文主要是介绍OKHttp源码解析sz,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

相关文章:OKHttp源码解析

OkHttp是一个高效的HTTP库:

  • 支持 SPDY ,共享同一个Socket来处理同一个服务器的所有请求
  • 如果SPDY不可用,则通过连接池来减少请求延时
  • 无缝的支持GZIP来减少数据流量
  • 缓存响应数据来减少重复的网络请求

会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,OkHttp会自动尝试下一个IP。OkHttp还处理了代理服务器问题和SSL握手失败问题。

使用 OkHttp 无需重写您程序中的网络代码。OkHttp实现了几乎和java.net.HttpURLConnection一样的API。如果您用了 Apache HttpClient,则OkHttp也提供了一个对应的okhttp-apache 模块。

OKHttp源码位置https://github.com/square/okhttp

一、总体设计

上面是OKHttp总体设计图,主要是通过Diapatcher不断从RequestQueue中取出请求(Call),根据是否已缓存调用Cache或Network这两类数据获取接口之一,从内存缓存或是服务器取得请求的数据。该引擎有同步和异步请求,同步请求通过Call.execute()直接返回当前的Response,而异步请求会把当前的请求Call.enqueue添加(AsyncCall)到请求队列中,并通过回调(Callback)的方式来获取最后结果。

接下来会介绍一些比较重要的类,另外一些基础IO方面的内容主要来之iohttp这个包。这些类的解释大部分来至文档介绍本身,所以在此不会翻译成中文,本人觉得英语原文更能准确表达它自身的作用。

二、OKHttp中重要的类

1.Route.java
The concrete route used by a connection to reach an abstract origin server.

connection可以使用一个具体的route来请求一个抽象的服务器。

When creating a connection the client has many options:

创建连接时,客户端有许多选项:

  • HTTP proxy: a proxy server may be explicitly configured for the client. Otherwise the {@linkplain java.net.ProxySelector proxy selector} is used. It may return multiple proxies to attempt.

      HTTP代理:可以为客户端明确地配置代理服务器。否则将使用代理选择器。它可能返回多个代理来尝试。

  • IP address: whether connecting directly to an origin server or a proxy, opening a socket requires an IP address. The DNS server may return multiple IP addresses to attempt.

       IP地址:无论是直接连接到源服务器还是代理服务器,打开套接字都需要IP地址。DNS服务器可能返回多个IP地址进行尝试。

  • TLS configuration: which cipher suites and TLS versions to attempt with the HTTPS connection.

       TLS配置:要尝试使用HTTPS连接的密码套件和TLS版本。

Each route is a specific selection of these options.每条路线都是这些选项的特定选择。
其实就是对地址的一个封装类,但是很重要。

2.Platform.java
Access to platform-specific features.

  • Server name indication (SNI): Supported on Android 2.3+.

      服务器名称指示

  • Session Tickets: Supported on Android 2.3+.

     会话许可证

  • Android Traffic Stats (Socket Tagging): Supported on Android 4.0+.

     Android流量统计

  • ALPN (Application Layer Protocol Negotiation): Supported on Android 5.0+. The APIs were present in Android 4.4, but that implementation was unstable.

     应用层协议协商

Supported on OpenJDK 7 and 8 (via the JettyALPN-boot library).
这个类主要是做平台适应性,针对Android2.3到5.0后的网络请求的适配支持。同时,在这个类中能看到针对不同平台,通过java反射不同的class是不一样的。

3.Connnection.java
The sockets and streams of an HTTP, HTTPS, or HTTPS+SPDY connection. May be used for multiple HTTP request/response exchanges. Connections may be direct to the origin server or via a proxy.

HTTP、HTTPS或HTTPS+SPDY连接的套接字和流。可用于多个HTTP请求/响应交换。连接可以直接到源服务器,也可以通过代理服务器。
Typically instances of this class are created, connected and exercised automatically by the HTTP client. Applications may use this class to monitor HTTP connections as members of a ConnectionPool.

通常,这个类的实例是由HTTP客户机自动创建、连接和执行的。应用程序可以使用这个类来监视作为连接池成员的HTTP连接。
Do not confuse this class with the misnamed HttpURLConnection, which isn’t so much a connection as a single request/response exchange.

不要将这个类与错误命名的HttpURLConnection混淆,后者与其说是一个连接,不如说是一个请求/响应交换。
Modern TLS  安全传输层协议(TLS)
There are tradeoffs when selecting which options to include when negotiating a secure connection to a remote host. Newer TLS options are quite useful:

在协商到远程主机的安全连接时,在选择要包括哪些选项时存在权衡。较新的TLS选项非常有用:

  • Server Name Indication (SNI) enables one IP address to negotiate secure connections for multiple domain names.

服务器名称指示(SNI)允许一个IP地址协商多个域名的安全连接。

  • Application Layer Protocol Negotiation (ALPN) enables the HTTPS port (443) to be used for different HTTP and SPDY protocols.

应用层协议协商(ALPN)允许将HTTPS端口(443)用于不同的HTTP和SPDY协议。

Unfortunately, older HTTPS servers refuse to connect when such options are presented. Rather than avoiding these options entirely, this class allows a connection to be attempted with modern options and then retried without them should the attempt fail.

不幸的是,旧的HTTPS服务器在出现此类选项时拒绝连接。此类不完全避免这些选项,而是允许使用现代选项尝试连接,然后在尝试失败时不使用这些选项重试。

4.ConnnectionPool.java
Manages reuse of HTTP and SPDY connections for reduced network latency. HTTP requests that share the same Address may share a Connection. This class implements the policy of which connections to keep open for future use.
The system-wide default uses system properties for tuning parameters:

管理HTTP和SPDY连接的重用,以减少网络延迟。共享同一地址的HTTP请求可能共享一个连接。此类实现了一个策略,该策略的连接将保持开放以供将来使用。

系统范围的默认值使用系统属性来调整参数:

  • http.keepAlive true if HTTP and SPDY connections should be pooled at all. Default is true.
  • http.maxConnections maximum number of idle connections to each to keep in the pool. Default is 5.
  • http.keepAliveDuration Time in milliseconds to keep the connection alive in the pool before closing it. Default is 5 minutes. This property isn’t used by HttpURLConnection.

如果HTTP和SPDY连接应该合并,则为http.keepalive true。默认值为true。

http.maxconnections每个要保留在池中的空闲连接的最大数目。默认值为5。

http.keepaliveduration关闭连接前保持池中连接活动的时间(毫秒)。默认为5分钟。httpurlConnection未使用此属性。

The default instance doesn’t adjust its configuration as system properties are changed. This assumes that the applications that set these parameters do so before making HTTP connections, and that this class is initialized lazily.

默认实例不会随着系统属性的更改而调整其配置。这假定设置这些参数的应用程序在进行HTTP连接之前执行此操作,并且此类是延迟初始化的。

5.Request.java
An HTTP request. Instances of this class are immutable if their body is null or itself immutable.(Builder模式)

HTTP请求。如果该类的主体为空或其本身不可变,则该类的实例是不可变的。(builder模式)

6.Response.java
An HTTP response. Instances of this class are not immutable: the response body is a one-shot value that may be consumed only once. All other properties are immutable.

HTTP响应。此类的实例不是不可变的:响应主体是一个一次性值,只能使用一次。所有其他属性都是不可变的。

7.Call.java
A call is a request that has been prepared for execution. A call can be canceled. As this object represents a single request/response pair (stream), it cannot be executed twice.

调用是已准备好执行的请求。可以取消通话。由于此对象表示单个请求/响应对(流),因此不能执行两次。

8.Dispatcher.java
Policy on when async requests are executed.

Each dispatcher uses an ExecutorService to run calls internally. If you supply your own executor, it should be able to run configured maximum number of calls concurrently.

执行异步请求时的策略。

每个调度器使用ExecutorService在内部运行调用。如果您提供自己的执行器,它应该能够同时运行配置的最大调用数。

9.HttpEngine.java
Handles a single HTTP request/response pair. Each HTTP engine follows this  lifecycle:

处理单个HTTP请求/响应对。每个HTTP引擎都遵循此生命周期:

  • It is created.
  • The HTTP request message is sent with sendRequest(). Once the request is sent it is an error to modify the request headers. After sendRequest() has been called the request body can be written to if it exists.

HTTP请求消息与sendRequest()一起发送。发送请求后,修改请求头是一个错误。调用sendRequest()之后,如果请求体存在,则可以将其写入。

  • The HTTP response message is read with readResponse(). After the response has been read the response headers and body can be read. All responses have a response body input stream, though in some instances this stream is empty.

使用readResponse()读取HTTP响应消息。在读取响应之后,可以读取响应头和主体。所有响应都有一个响应主体输入流,但在某些情况下,该流是空的。

The request and response may be served by the HTTP response cache, by the network, or by both in the event of a conditional GET.

请求和响应可以由HTTP响应缓存提供,也可以由网络提供,或者在条件GET的情况下由两者提供。

10.Internal.java
Escalate internal APIs in {@code com.squareup.okhttp} so they can be used from OkHttp’s implementation packages. The only implementation of this interface is in {@link com.squareup.okhttp.OkHttpClient}.

升级@code com.squareup.okhttp中的内部API,以便可以从okhttp的实现包中使用它们。此接口的唯一实现是@link com.squareup.okhttp.okhttpclient。

11.Cache.java
Caches HTTP and HTTPS responses to the filesystem so they may be reused, saving time and bandwidth.

将HTTP和HTTPS响应缓存到文件系统,以便可以重用它们,从而节省时间和带宽。

Cache Optimization
To measure cache effectiveness, this class tracks three statistics:

  • Request Count: the number of HTTP requests issued since this cache was created.
  • Network Count: the number of those requests that required network use.
  • Hit Count: the number of those requests whose responses were served by the cache.

Sometimes a request will result in a conditional cache hit. If the cache contains a stale copy of the response, the client will issue a conditional GET. The server will then send either the updated response if it has changed, or a short ‘not modified’ response if the client’s copy is still valid. Such responses increment both the network count and hit count.
The best way to improve the cache hit rate is by configuring the web server to return cacheable responses. Although this client honors all HTTP/1.1 (RFC 2068) cache headers, it doesn’t cache partial responses.

Force a Network Response
In some situations, such as after a user clicks a ‘refresh’ button, it may be necessary to skip the cache, and fetch data directly from the server. To force a full refresh, add the {@code no-cache} directive:

1
connection.addRequestProperty("Cache-Control", "no-cache")

 

If it is only necessary to force a cached response to be validated by the server, use the more efficient {@code max-age=0} instead:

1
connection.addRequestProperty("Cache-Control", "max-age=0");

 

Force a Cache Response
Sometimes you’ll want to show resources if they are available immediately, but not otherwise. This can be used so your application can show something while waiting for the latest data to be downloaded. To restrict a request to locally-cached resources, add the {@code only-if-cached} directive:

1
2
3
4
5
6
7
try {connection.addRequestProperty("Cache-Control", "only-if-cached");InputStream cached = connection.getInputStream();// the resource was cached! show it} catch (FileNotFoundException e) {// the resource was not cached}

 

This technique works even better in situations where a stale response is better than no response. To permit stale cached responses, use the {@code max-stale} directive with the maximum staleness in seconds:

1
2
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
connection.addRequestProperty("Cache-Control", "max-stale=" + maxStale);

 

12.OkHttpClient.java
Configures and creates HTTP connections. Most applications can use a single OkHttpClient for all of their HTTP requests - benefiting from a shared response cache, thread pool, connection re-use, etc.

Instances of OkHttpClient are intended to be fully configured before they’re shared - once shared they should be treated as immutable and can safely be used to concurrently open new connections. If required, threads can call clone to make a shallow copy of the OkHttpClient that can be safely modified with further configuration changes.

##请求流程图
下面是关于OKHttp的请求流程图

##详细类关系图
由于整个设计类图比较大,所以本人将从核心入口client、cache、interceptor、网络配置、连接池、平台适配性…这些方面来逐一进行分析源代码的设计。
下面是核心入口OkHttpClient的类设计图

从OkHttpClient类的整体设计来看,它采用门面模式来。client知晓子模块的所有配置以及提供需要的参数。client会将所有从客户端发来的请求委派到相应的子系统去。
在该系统中,有多个子系统、类或者类的集合。例如上面的cache、连接以及连接池相关类的集合、网络配置相关类集合等等。每个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。同时,OkHttpClient可以看作是整个框架的上下文。
通过类图,其实很明显反应了该框架的几大核心子系统;路由、连接协议、拦截器、代理、安全性认证、连接池以及网络适配。从client大大降低了开发者使用难度。同时非常明了的展示了该框架在所有需要的配置以及获取结果的方式。

在接下来的几个Section中将会结合子模块核心类的设计,从该框架的整体特性上来分析这些模块是如何实现各自功能。以及各个模块之间是如何相互配合来完成客户端各种复杂请求。

 

 

这篇关于OKHttp源码解析sz的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/633702

相关文章

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

Linux中shell解析脚本的通配符、元字符、转义符说明

《Linux中shell解析脚本的通配符、元字符、转义符说明》:本文主要介绍shell通配符、元字符、转义符以及shell解析脚本的过程,通配符用于路径扩展,元字符用于多命令分割,转义符用于将特殊... 目录一、linux shell通配符(wildcard)二、shell元字符(特殊字符 Meta)三、s

使用Python实现批量访问URL并解析XML响应功能

《使用Python实现批量访问URL并解析XML响应功能》在现代Web开发和数据抓取中,批量访问URL并解析响应内容是一个常见的需求,本文将详细介绍如何使用Python实现批量访问URL并解析XML响... 目录引言1. 背景与需求2. 工具方法实现2.1 单URL访问与解析代码实现代码说明2.2 示例调用

SSID究竟是什么? WiFi网络名称及工作方式解析

《SSID究竟是什么?WiFi网络名称及工作方式解析》SID可以看作是无线网络的名称,类似于有线网络中的网络名称或者路由器的名称,在无线网络中,设备通过SSID来识别和连接到特定的无线网络... 当提到 Wi-Fi 网络时,就避不开「SSID」这个术语。简单来说,SSID 就是 Wi-Fi 网络的名称。比如

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)

《使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)》在现代软件开发中,处理JSON数据是一项非常常见的任务,无论是从API接口获取数据,还是将数据存储为JSON格式,解析... 目录1. 背景介绍1.1 jsON简介1.2 实际案例2. 准备工作2.1 环境搭建2.1.1 添加

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

在C#中合并和解析相对路径方式

《在C#中合并和解析相对路径方式》Path类提供了几个用于操作文件路径的静态方法,其中包括Combine方法和GetFullPath方法,Combine方法将两个路径合并在一起,但不会解析包含相对元素... 目录C#合并和解析相对路径System.IO.Path类幸运的是总结C#合并和解析相对路径对于 C

Java解析JSON的六种方案

《Java解析JSON的六种方案》这篇文章介绍了6种JSON解析方案,包括Jackson、Gson、FastJSON、JsonPath、、手动解析,分别阐述了它们的功能特点、代码示例、高级功能、优缺点... 目录前言1. 使用 Jackson:业界标配功能特点代码示例高级功能优缺点2. 使用 Gson:轻量

Java如何接收并解析HL7协议数据

《Java如何接收并解析HL7协议数据》文章主要介绍了HL7协议及其在医疗行业中的应用,详细描述了如何配置环境、接收和解析数据,以及与前端进行交互的实现方法,文章还分享了使用7Edit工具进行调试的经... 目录一、前言二、正文1、环境配置2、数据接收:HL7Monitor3、数据解析:HL7Busines