当前位置: 首页 > article >正文

OkHttp深度解析:请求流程、分发器机制、拦截器工作及TCP连接复用

目录

一、OkHttp请求的请求流程是怎样的?

二、OkHttp分发器是怎样工作的?

2.1 请求队列与线程池维护

2.2 异步请求处理

2.3 同步请求处理

2.4 请求执行

2.5 请求完成处理:

2.6 线程池设计

三、OkHttp拦截器是如何工作的?

四、应用拦截器和网络拦截器的区别?

4.1 调用顺序和位置

4.2 功能和用途

五、OkHttp 如何复用TCP 连接的?

5.1 具体过程

5.2 优势

相关推荐


一、OkHttp请求的请求流程是怎样的?

    public void sendOkHttp(){
        //创建OkHttpClient对象
        OkHttpClient client = new OkHttpClient();
        //创建Request
        Request request = new Request.Builder()
                .url("https://shuaici.blog.csdn.net/")
                .build();
        //创建Call对象client.newCall(request)
        Call call = client.newCall(request);
        //通过execute()方法获得请求响应的Response对象
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {}

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if(response.isSuccessful()){
                    String result = response.body().string();
                    //处理UI需要切换到UI线程处理
                }
            }
        });
    }

请求流程总结

  1. 创建OkHttpClient实例:OkHttpClient是OKHttp库的核心类,用于发送HTTP请求和接收HTTP响应。
  2. 创建Request对象:Request对象封装了HTTP请求的所有信息,包括URL、请求方法(GET、POST等)、请求头部和请求体等。
  3. 执行请求
    1. 通过 OkHttpClient 的 newCall 方法创建 Call 对象。这里的Call是一个接口,实际返回的是它的唯一实现子类RealCall对象。
    2. 同步请求:通过调用call.execute()方法真正发起网络请求,并返回一个Response对象。这种方法会阻塞当前线程,直到请求完成并返回响应。
    3. 异步请求:通过调用call.enqueue(callback)方法真正发起网络请求,并传入一个Callback对象。当请求完成时,OKHttp会自动调用Callback对象的onResponseonFailure方法来处理响应或错误。
  4. 处理响应:在获取到Response对象后,可以通过调用其方法(如body().string())来获取响应体的内容,并进行相应的处理。

二、OkHttp分发器是怎样工作的?

        OkHttp分发器(Dispatcher)的主要作用是调配请求任务,它内部维护了队列和线程池来管理请求的执行。以下是OKHttp分发器的工作机制:

2.1 请求队列与线程池维护

  • 分发器内部主要维护了两个队列:readyAsyncCalls(等待执行的异步请求队列)和runningAsyncCalls(正在执行的异步请求队列),以及runningSyncCalls(正在执行的同步请求队列)。
  • 分发器还包含一个线程池executorService,用于执行请求任务。

2.2 异步请求处理

  • 当发起异步请求时,分发器会检查:
  1. 同时请求的异步任务数不得大于64(maxRequests)和
  2. readyAsyncCalls队列中取出异步任务其Host,在runningAsyncCalls中不得大于5。
  3. 则将请求添加到runningAsyncCalls队列并立即执行;如果超过了,则将请求加入到readyAsyncCalls队列中等待。

2.3 同步请求处理

        对于同步请求,分发器仅记录请求(放入runningSyncCalls队列中),因为同步请求不需要线程池,也不存在并发限制,所以分发器仅做记录,后续按照加入队列的顺序同步请求即可。

2.4 请求执行

        请求执行是通过分发器将任务分配给拦截器链来完成的。拦截器链负责完成网络请求过程,包括请求重试、缓存处理、建立连接等一系列操作。

2.5 请求完成处理:

        请求完成后,分发器会runningAsyncCallsrunningSyncCalls队列中移除对应的请求,并检查是否有等待执行的请求,如果有,则将等待的请求加入到线程池执行

2.6 线程池设计

        分发器中的线程池设计为:核心线程数为0,最大线程数为Int.MAX_VALUE,空闲时间为60秒,工作队列为SynchronousQueue()。这种设计意味着,当有任务需要执行时,如果线程池中没有可用线程,会直接创建新线程来处理任务。

三、OkHttp拦截器是如何工作的?

        OKHttp的拦截器机制是其核心功能之一,它基于责任链模式实现。每个拦截器都可以处理请求或响应,并将请求或响应传递给下一个拦截器。拦截器的工作机制如下:

  1. 在发起HTTP请求时,OKHttp会依次调用每个拦截器的intercept()方法,将请求传递给下一个拦截器,直到请求被发送到服务器或被拦截器拦截并返回响应为止。
  2. 在接收到响应后,OKHttp会依次调用每个拦截器的intercept()方法,将响应传递给下一个拦截器,直到响应被处理完毕或被拦截器拦截并返回新的响应为止。
  3. 拦截器在处理请求和响应时,可以通过Request和Response对象来获取和修改请求和响应的信息。
/**
 * 获取响应的拦截器链。
 * 
 * @return Response 对象,包含服务器的响应。
 * @throws IOException 如果发生 I/O 错误。
 */
Response getResponseWithInterceptorChain() throws IOException {
    // 构建完整的拦截器栈。
    List<Interceptor> interceptors = new ArrayList<>();

    // 1. 应用拦截器:用户自定义的拦截器,可以在此拦截器中添加自定义逻辑。
    interceptors.addAll(client.interceptors()); 

    // 2. 重试重定向拦截器:处理请求重试和重定向逻辑。
    interceptors.add(new RetryAndFollowUpInterceptor(client)); 
    // 3. 桥接拦截器:处理请求和响应的转换,例如将请求转换为HTTP/2请求。
    interceptors.add(new BridgeInterceptor(client.cookieJar())); 
    // 4. 缓存拦截器:处理缓存逻辑,决定是否从缓存中读取响应或将响应存储到缓存中。
    interceptors.add(new CacheInterceptor(client.internalCache())); 
    // 5. 连接拦截器:处理与服务器建立连接的逻辑,包括DNS解析和TLS握手。
    interceptors.add(new ConnectInterceptor(client)); 

    // 如果不是WebSocket请求,添加网络拦截器。
    if (!forWebSocket) {
        // 6. 网络拦截器:用户自定义的网络层面的拦截器,可以在此拦截器中添加网络层面的自定义逻辑。
        interceptors.addAll(client.networkInterceptors()); 
    }

    // 7. 服务器调用拦截器:实际向服务器发送请求并接收响应的拦截器,如果是WebSocket请求则特殊处理。
    interceptors.add(new CallServerInterceptor(forWebSocket)); 

    // ......
}

四、应用拦截器和网络拦截器的区别?

4.1 调用顺序和位置

  • 应用拦截器:先经过应用拦截器,再进入内核,再进入网络拦截器。应用拦截器只关心发起的请求和最终得到的结果,不关心重定向或重试等中间响应。
  • 网络拦截器:可以操作重定向或重试的中间响应。如果应用拦截器决定短路并以缓存返回,则网络拦截器就得不到调用

4.2 功能和用途

  • 应用拦截器:常用于日志记录、身份验证、修改请求或响应等操作。它们可以拦截Chain.proceed()或多次调用Chain.proceed()。
  • 网络拦截器:更侧重于网络层面的操作,如处理重定向、重试策略等。

五、OkHttp 如何复用TCP 连接的?

        OkHttp通过其内置的连接池机制高效地复用了TCP连接。连接池会维护一组已经建立的TCP连接,并在需要发送新的HTTP请求时重用这些连接,而不是每次请求都重新建立一个新的TCP连接。

5.1 具体过程

  1. 检查连接池:当OkHttp需要发送一个新的HTTP请求时,它首先会检查连接池中是否有可用的TCP连接。这个检查过程是基于目标服务器的IP地址和端口来进行的。
  2. 复用连接:如果连接池中存在与目标服务器匹配的可用TCP连接,OkHttp就会复用该连接来发送HTTP请求。这意味着,同一个TCP连接上可以发送多个HTTP请求和接收相应的响应,从而减少了每次请求时建立新连接的开销。
  3. 管理连接生命周期:OkHttp会根据配置的参数(如最大空闲连接数、连接空闲超时等)自动管理连接池中的连接。如果某个连接在一段时间内没有被使用,OkHttp会自动将其关闭,以释放系统资源。

5.2 优势

  1. 提高性能:通过复用TCP连接,OkHttp显著减少了连接建立和关闭的开销,从而提高了HTTP请求的响应速度和整体性能。
  2. 减少资源消耗:复用连接可以减少系统资源的消耗,尤其是在高并发的情况下,能够有效减轻服务器的负担。
  3. 降低网络延迟:已经建立的TCP连接可以直接用于发送新的HTTP请求,无需重新进行TCP三次握手等操作,从而降低了网络延迟。

相关推荐

Android OkHttp使用和源码详解-CSDN博客文章浏览阅读1.5k次,点赞10次,收藏5次。OkHttp 是一套处理 HTTP 网络请求的依赖库,由 Square 公司设计研发并开源,目前可以在 Java 和 Kotlin 中使用。对于 Android App 来说,OkHttp 现在几乎已经占据了所有的网络请求操作,RetroFit + OkHttp 实现网络请求似乎成了一种标配。因此它也是每一个 Android 开发工程师的必备技能,了解其内部实现原理可以更好地进行功能扩展、封装以及优化。_com.squareup.okiohttps://shuaici.blog.csdn.net/article/details/120174041Android OkHttp+Retrofit+Rxjava+Hilt实现网络请求框架-CSDN博客文章浏览阅读3.6k次,点赞37次,收藏47次。本文通过OkHttp+Retrofit+Rxjava+Hilt实现一个网络请求框。 最终代码特别省事。_android response.body().getdata()https://shuaici.blog.csdn.net/article/details/121384534


http://www.kler.cn/a/461945.html

相关文章:

  • RocketMQ面试题:进阶部分
  • 【保姆级】sql注入之堆叠注入
  • Ungoogled Chromium127 编译指南 MacOS 篇(一)- 项目介绍
  • 【数据结构】树链刨分
  • 深入解析爬虫中的算法设计:提升效率与准确度
  • Golang的并发编程实战经验
  • 算法-Excel字母表转换成数字 26进制转换
  • Mono里运行C#脚本17—load_tables
  • ica1
  • 青云客-网页端语音机器人
  • 笔上云世界微服务版
  • LabVIEW声波谐振管自动化测量系统
  • 33. 简易内存池
  • 使用jest-axe为你的前端项目自动化测试
  • 免费又开源:企业级物联网平台的新选择 ThingsPanel
  • 如何使用 OpenCV 扫描图像、查找表和时间测量
  • 数据结构与算法之查找
  • Python大数据可视化:基于大数据技术的共享单车数据分析与辅助管理系统_flask+hadoop+spider
  • C++ 内存
  • 混合合并两个pdf文件
  • FastAPI 集成 MySQL 和 Redis:模型与模式生成实践
  • ARM 架构--通用寄存器状态寄存器控制寄存器特殊用途寄存器
  • 【《python爬虫入门教程11--重剑无峰168》】
  • 算法进阶:贪心算法
  • 自学记录鸿蒙API 13:PreviewKit从文件预览到应用开发
  • 详细讲一下React中的路由React Router