OkHttp原理分析(一)

436 阅读1分钟

OkHttp execute同步请求方法

Call是一个接口,RealCall是Call的具体实现。

RealCall.kt
override fun execute(): Response {
  synchronized(this) {
    check(!executed) { "Already Executed" }
    executed = true
  }
  transmitter.timeoutEnter()
  transmitter.callStart()
  try {
    client.dispatcher.executed(this)
    return getResponseWithInterceptorChain()
  } finally {
    client.dispatcher.finished(this)
  }
}

将RealCall添加到正在执行的同步请求队列中

Dispatcher.kt
@Synchronized internal fun executed(call: RealCall) {
    runningSyncCalls.add(call)
  }
RealInterceptorChain.kt
fun getResponseWithInterceptorChain(): Response {
    // 创建一个拦截器栈,最先入栈最后执行
    val interceptors = mutableListOf<Interceptor>()
    interceptors += client.interceptors
    interceptors += RetryAndFollowUpInterceptor(client)
    interceptors += BridgeInterceptor(client.cookieJar)
    interceptors += CacheInterceptor(client.cache)
    interceptors += ConnectInterceptor
    if (!forWebSocket) {
      interceptors += client.networkInterceptors
    }
    interceptors += CallServerInterceptor(forWebSocket)
    // 创建一个拦截器链
    val chain = RealInterceptorChain(interceptors, transmitter, null, 0, originalRequest, this,
        client.connectTimeoutMillis, client.readTimeoutMillis, client.writeTimeoutMillis)

    var calledNoMoreExchanges = false
    try {
      // 执行拦截器链
      val response = chain.proceed(originalRequest)
      if (transmitter.isCanceled) {
        response.closeQuietly()
        throw IOException("Canceled")
      }
      return response
    } catch (e: IOException) {
      calledNoMoreExchanges = true
      throw transmitter.noMoreExchanges(e) as Throwable
    } finally {
      if (!calledNoMoreExchanges) {
        transmitter.noMoreExchanges(null)
      }
    }
}
override fun proceed(request: Request): Response {
  return proceed(request, transmitter, exchange)
}
fun proceed(request: Request, transmitter: Transmitter, exchange: Exchange?): Response {
  if (index >= interceptors.size) throw AssertionError()
  // 
  calls++
  ...
  // 调用下一个拦截器
  val next = RealInterceptorChain(interceptors, transmitter, exchange,
    index + 1, request, call, connectTimeout, readTimeout, writeTimeout)
  val interceptor = interceptors[index]
  // 执行拦截器
  @Suppress("USELESS_ELVIS")
  val response = interceptor.intercept(next) ?: throw NullPointerException(
    "interceptor $interceptor returned null")
  ...
  return response
}

OkHttp enqueue异步请求方法

override fun enqueue(responseCallback: Callback) {
  synchronized(this) {
    check(!executed) { "Already Executed" }
    executed = true
  }
  transmitter.callStart()
  client.dispatcher.enqueue(AsyncCall(responseCallback))
}
internal fun enqueue(call: AsyncCall) {
  synchronized(this) {
    readyAsyncCalls.add(call)
    if (!call.get().forWebSocket) {
      val existingCall = findExistingCallWithHost(call.host())
      if (existingCall != null) call.reuseCallsPerHostFrom(existingCall)
    }
  }
  promoteAndExecute()
}
private fun promoteAndExecute(): Boolean {
  assert(!Thread.holdsLock(this))

  val executableCalls = mutableListOf<AsyncCall>()
  val isRunning: Boolean
  synchronized(this) {
    val i = readyAsyncCalls.iterator()
    while (i.hasNext()) {
      val asyncCall = i.next()
      // 最多正在运行的HTTP请求数
      if (runningAsyncCalls.size >= this.maxRequests) break 
      // 一个主机最大运行HTTP请求数
      if (asyncCall.callsPerHost().get() >= this.maxRequestsPerHost) continue
      i.remove()
      asyncCall.callsPerHost().incrementAndGet()
      executableCalls.add(asyncCall)
      runningAsyncCalls.add(asyncCall)
    }
    isRunning = runningCallsCount() > 0
  }
  for (i in 0 until executableCalls.size) {
    val asyncCall = executableCalls[i]
    asyncCall.executeOn(executorService)
  }
  return isRunning
}
override fun run() {
  threadName("OkHttp ${redactedUrl()}") {
    var signalledCallback = false
    transmitter.timeoutEnter()
    try {
      // 在子线程中执行
      val response = getResponseWithInterceptorChain()
      signalledCallback = true
      // 请求成功回调
      responseCallback.onResponse(this@RealCall, response)
    } catch (e: IOException) {
      if (signalledCallback) {
        Platform.get().log(INFO, "Callback failure for ${toLoggableString()}", e)
      } else {
        // 抛出异常回调
        responseCallback.onFailure(this@RealCall, e)
      }
    } finally {
      // 请求结束
      client.dispatcher.finished(this)
    }
  }
}