解读OkHttp3之StreamAllocation

说到StreamAllocation的解读,需要先看多上一篇章对okHttp3框架的解读:

这篇主要分析StreamAllocation的源码:

 

public StreamAllocation(ConnectionPool connectionPool, Address address, Call call,
    EventListener eventListener, Object callStackTrace) {
  this.connectionPool = connectionPool;//连接池管理
  this.address = address;
  this.call = call;//realCall
  this.eventListener = eventListener;
  this.routeSelector = new RouteSelector(address, routeDatabase(), call, eventListener);//routeDatabase()(ConnectionPool类的routeDatabase常量), 该对象为处理连接到原服务器的路由
  this.callStackTrace = callStackTrace;
}

构造函数中,初始化了一个连接到原服务器的路由地址管理工具;这里展开讲解下RouteSelector:

 

public RouteSelector(Address address, RouteDatabase routeDatabase, Call call,
    EventListener eventListener) {
  this.address = address;
  this.routeDatabase = routeDatabase;
  this.call = call;
  this.eventListener = eventListener;

  resetNextProxy(address.url(), address.proxy());
}

关键方法resetNextProxy:

 

private void resetNextProxy(HttpUrl url, Proxy proxy) {
  if (proxy != null) {
    // If the user specifies a proxy, try that and only that.
    proxies = Collections.singletonList(proxy);//如果okhttp配置的代理不为空的话,直接使用ok配置的代理
  } else {
    // Try each of the ProxySelector choices until one connection succeeds.
    List<Proxy> proxiesOrNull = address.proxySelector().select(url.uri());//尝试系统的代理选择器
    proxies = proxiesOrNull != null && !proxiesOrNull.isEmpty()
        ? Util.immutableList(proxiesOrNull)
        : Util.immutableList(Proxy.NO_PROXY);//直连,不使用代理
  }
  nextProxyIndex = 0;//代理获取计数器
}

接下来,看看StreamAllocation的newStream方法,这个方法在拦截器ConnectInterceptor中调用,用来打开连接:

 

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

  try {
    RealConnection resultConnection = findHealthyConnection(connectTimeout, readTimeout,
        writeTimeout, connectionRetryEnabled, doExtensiveHealthChecks);//打开连接
    HttpCodec resultCodec = resultConnection.newCodec(client, chain, this);//获取http协议版本解析器

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

这里我们看看HttpCodec是做什么的:

 

public interface HttpCodec {
  /**
   * The timeout to use while discarding a stream of input data. Since this is used for connection
   * reuse, this timeout should be significantly less than the time it takes to establish a new
   * connection.
   */
  int DISCARD_STREAM_TIMEOUT_MILLIS = 100;

  /** Returns an output stream where the request body can be streamed. */
  Sink createRequestBody(Request request, long contentLength);

  /** This should update the HTTP engine's sentRequestMillis field. */
  void writeRequestHeaders(Request request) throws IOException;

  /** Flush the request to the underlying socket. */
  void flushRequest() throws IOException;

  /** Flush the request to the underlying socket and signal no more bytes will be transmitted. */
  void finishRequest() throws IOException;

  /**
   * Parses bytes of a response header from an HTTP transport.
   *
   * @param expectContinue true to return null if this is an intermediate response with a "100"
   *     response code. Otherwise this method never returns null.
   */
  Response.Builder readResponseHeaders(boolean expectContinue) throws IOException;//读取响应头部

  /** Returns a stream that reads the response body. */
  ResponseBody openResponseBody(Response response) throws IOException;//返回读取响应体的流

  /**
   * Cancel this stream. Resources held by this stream will be cleaned up, though not synchronously.
   * That may happen later by the connection pool thread.
   */
  void cancel();//取消流,非同步,
}

可以看到httpCodec的继承类,都是实现了请求、响应头部的写入与读取,以及创建请求、响应实体的流;

具体实现类在http1Codec、http2Codec包中,这里不做进一步解析;

至此StreamAllocation类就分析完毕了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值