OkHttp解析四(拦截器)

本文详细解析了OkHttp的拦截器机制,包括ConnectInterceptor和CallServerInterceptor的作用。ConnectInterceptor负责建立与服务器的连接,管理连接与数据流。CallServerInterceptor则负责请求服务器,处理各种请求方式的响应头,确保正确发送和接收HTTP数据。
摘要由CSDN通过智能技术生成

拦截器

ConnectInterceptor

打开与目标服务器的连接,并执行下一个拦截器。

@Override public Response intercept(Chain chain) throws IOException {
   
    RealInterceptorChain realChain = (RealInterceptorChain) chain;
    Request request = realChain.request();
    StreamAllocation streamAllocation = realChain.streamAllocation();

    // We need the network to satisfy this request. Possibly for validating a conditional GET.
    boolean doExtensiveHealthChecks = !request.method().equals("GET");
    HttpCodec httpCodec = streamAllocation.newStream(client, chain, doExtensiveHealthChecks);
    RealConnection connection = streamAllocation.connection();

    return realChain.proceed(request, streamAllocation, httpCodec, connection);
  }

StreamAllocation这个对象是在第一个拦截器:重定向拦截器(RetryAndFollowUpInterceptor)创建的,但是真正使用的地方却在这里。
当一个请求发出,需要建立连接,连接建立后需要使用流用来读写数据。
这个StreamAllocation就是协调请求、连接与数据流三者之间的关系,它负责为一次请求寻找连接,然后获得流来实现网络通信。

StreamAllocation中简单来说就是维护连接:RealConnection——封装了Socket与一个Socket连接池。可复用的RealConnection需要:

public HttpCodec newStream(
            OkHttpClient client, Interceptor.Chain chain, boolean doExtensiveHealthChecks) {
   
        int connectTimeout = chain.connectTimeoutMillis();
        int readTimeout = chain.readTimeoutMillis();
        int writeTimeout = chain.writeTimeoutMillis();
        int pingIntervalMillis = client.pingIntervalMillis();
        boolean connectionRetryEnabled = client.retryOnConnectionFailure();

        try {
   
            //todo  找到一个健康的连接
            RealConnection resultConnection = findHealthyConnection(connectTimeout, readTimeout,
                    writeTimeout, pingIntervalMillis, connectionRetryEnabled,
                    doExtensiveHealthChecks);
            //todo 利用连接实例化流HttpCodec对象,如果是HTTP/2返回Http2Codec,否则返回Http1Codec
            HttpCodec resultCodec = resultConnection.newCodec(client, chain, this);

            synchronized (connectionPool) {
   
                codec = resultCodec;
                return resultCodec;
            }
        } catch (IOException e) {
   
            throw new RouteException(e);
        }
    }

这里使用的newStream方法实际上就是去查找或者建立一个与请求主机有效的连接,返回的HttpCodec中包含了输入输出流,并且封装了对HTTP请求报文的编码与解码,直接使用它就能够与请求主机完成HTTP通信。

/**
 * Returns true if this connection can carry a stream allocation to {@code address}. If non-null
 * {@code route} is the resolved route for a connection.
 */
public boolean isEligible(Address address, @Nullable Route route) {
   
    // If this connection is not accepting new streams, we're done.
    if (allocations.size() >= allocationLimit || noNewStreams) return false;

    // If the non-host fields of the address don't overlap, we're done.
    if (!Internal<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值