OkHttp请求流程

作者: shawn_yy | 来源:发表于2017-08-24 17:20 被阅读74次

    http 第一次同步请求流程详细分析

    请求代码

    //单利
     val client:OkHttpClient = OkHttpClient()
                    .newBuilder().build()
    
    
     var request = Request.Builder()
             .url("http://www.baidu.com")
             .build()
    
     Thread(Runnable {
         client.newCall(request).execute().use {
             print(" body == ${it.body()!!.string()}")
         }
     }).start()
    
    
    第一步 构建一个Request

    通过建造者模式构建一个Request。Request包含了HttpUrl,请求方式,端口,参数等信息

    HttpUrl包含scheme host port 等信息

    新建一个Call并同步执行
    1.client.newCall(request)
       ```
       @Override public Call newCall(Request request) {
           return new RealCall(this, request, false /* for web socket */);
         }
       ```
       RealCall的构造方法,在构造RealCall的时候,会构造一个RetryAndFollowUpInterceptor类,这个类主要负责处理重试和重定向的
       eventListener3.8.1还没有实现。
       ```
       RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
           final EventListener.Factory eventListenerFactory = client.eventListenerFactory();
    
           this.client = client;
           this.originalRequest = originalRequest;
           this.forWebSocket = forWebSocket;
           this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
    
           // TODO(jwilson): this is unsafe publication and not threadsafe.
           this.eventListener = eventListenerFactory.create(this);
         }
       ```
    

    2.RealCall.execute()
    这里面同步执行请求,主要是getResponseWithInterceptorChain()。
    
    ```
    Response getResponseWithInterceptorChain() throws IOException {
        // Build a full stack of interceptors.
        List<Interceptor> interceptors = new ArrayList<>();
        interceptors.addAll(client.interceptors());
        interceptors.add(retryAndFollowUpInterceptor);
        interceptors.add(new BridgeInterceptor(client.cookieJar()));
        interceptors.add(new CacheInterceptor(client.internalCache()));
        interceptors.add(new ConnectInterceptor(client));
        if (!forWebSocket) {
          interceptors.addAll(client.networkInterceptors());
        }
        interceptors.add(new CallServerInterceptor(forWebSocket));
    
        Interceptor.Chain chain = new RealInterceptorChain(
            interceptors, null, null, null, 0, originalRequest);
        return chain.proceed(originalRequest);
      }
    ```
    在 chain.proceed()的时候会用一种递归的方式来执行所有拦截器的intercept()方法。
    
    假定client.interceptors().size() 为0.这段代码的执行chain.proceed的时候执行循序为
    RetryAndFollowUpInterceptor>BridgeInterceptor>CacheInterceptor>ConnectInterceptor>CallServerInterceptor
    

    3.RetryAndFollowUpInterceptor.intercept()
    ```
    streamAllocation = new StreamAllocation(
                   client.connectionPool(), createAddress(request.url()), callStackTrace);
    ```
    创建Address,并用它来创建StreamAllocation。StreamAllocation组织Connections,Streams和Calls的关系。
    然后执行
    ```
    response = ((RealInterceptorChain) chain).proceed(request, streamAllocation, null, null);
    ```
    这个会将创建好的streamAllocation传递给BridgeInterceptor的intercept()方法
    

    4.BridgeInterceptor.intercept()
    这个拦截器的主要功能是:
    > 处理请求头(header),将自定义的头和协议必须的头合在一起,
    如果有自定义使用自定义的,没有就生成默认头
    > 处理cookie
    
    头部信息处理完毕后 执行
    ```
    Response networkResponse = chain.proceed(requestBuilder.build());
    ```
    将处理后的新Request传递给下一个拦截器
    

    5.CacheInterceptor.intercept()
     本拦截器主要是处理缓存的。
    
     执行
    
    ```
    networkResponse = chain.proceed(networkRequest);
    ```
    将处理后的新Request传递给下一个拦截器
    

    6.ConnectInterceptor.intercept()
    本拦截器主要是建立RealConnection并从这个连接中读取数据流,这个RealConnection可能是新创建的也可能是从缓存池中得到的,
    得到RealConnection后调用resultConnection.newCodec(client, this)创建HttpCodec
    
    执行
    
    realChain.proceed(request, streamAllocation, httpCodec, connection);
    
    最后将HttpCodec和RealConnection传递给最后一个拦截器。
    

    7.CallServerInterceptor.intercept()
    本拦截器是最后一个,主要功能是根据RealConnection和HttpCodec组装Response,并将Response返回给6的拦截器
    

    8.ConnectInterceptor.intercept()方法中 proceed 之后的代码
    得到返回值之后没有任何操作直接返回给上级CacheInterceptor
    

    9.CacheInterceptor.intercept()方法中 proceed 之后的代码
    得到由ConnectInterceptor返回的Response 根据缓存策略将其缓存起来,之后返回改Response
    

    10.BridgeInterceptor.intercept()方法中 proceed 之后的代码
    得到CacheInterceptor返回的Response 将之前组装的Request给Response并返回改Response
    如果请求头有其他对Response的配置,还会按照请求头的配置对Response做相应的处理
    最后将处理好的Response返回
    

    11.RetryAndFollowUpInterceptor.intercept()方法中 proceed 之后的代码
    得到BridgeInterceptor返回的Response ,
    根据返回的Response的返回码,判断是不是重定向或者其他的操作,
    如果是从定向则从 *3* 重新开始
    如果返回正常的Response,最后返回Response
    

    12.RealCall#getResponseWithInterceptorChain()
    该方法得到RetryAndFollowUpInterceptor返回的Response
    
    然后将Response返回给RealCall#executed()
    
    End 到此一次同步请求完毕

    相关文章

      网友评论

        本文标题:OkHttp请求流程

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