【问题标题】:Why retryOnConnectionFailure(true) is a solution to OkHttp Error : java.io.IOException: unexpected end of stream为什么 retryOnConnectionFailure(true) 是 OkHttp 错误的解决方案:java.io.IOException: unexpected end of stream
【发布时间】:2021-02-17 05:39:24
【问题描述】:

当我找到this 时,我已经有很长一段时间出现此错误。 使用 swankjesse 提供的解决方案后,错误消失了。 我似乎无法理解为什么这是一个解决方案。我在网上找不到任何东西 解释了这种方法解决错误的原因。

OkHttp 文档说:

retryOnConnectionFailure

配置此客户端以在出现连接问题时重试或不重试 遭遇。默认情况下,此客户端静默地从 以下问题:

无法访问的 IP 地址。如果 URL 的主机有多个 IP 地址,未能到达任何单独的 IP 地址不会失败 总体要求。这可以提高多宿主的可用性 服务。

过时的池连接。 ConnectionPool 重用套接字 减少请求延迟,但这些连接偶尔会超时 出去。

无法访问代理服务器。 ProxySelector 可用于按顺序尝试多个代理服务器,最终回退到一个 直接连接。

以上是可以理解的,但它并不能说明为什么这是解决该错误的方法。

提前致谢。

【问题讨论】:

    标签: java android retrofit okhttp


    【解决方案1】:

    此标志允许 OkHttpClient 在某些条件为真(即已知是安全的)时多次重试请求。如果没有这个标志,客户端将立即返回错误,以便客户端决定是否以及何时重试。

      private fun isRecoverable(e: IOException, requestSendStarted: Boolean): Boolean {
        // If there was a protocol problem, don't recover.
        if (e is ProtocolException) {
          return false
        }
    
        // If there was an interruption don't recover, but if there was a timeout connecting to a route
        // we should try the next route (if there is one).
        if (e is InterruptedIOException) {
          return e is SocketTimeoutException && !requestSendStarted
        }
    
        // Look for known client-side or negotiation errors that are unlikely to be fixed by trying
        // again with a different route.
        if (e is SSLHandshakeException) {
          // If the problem was a CertificateException from the X509TrustManager,
          // do not retry.
          if (e.cause is CertificateException) {
            return false
          }
        }
        if (e is SSLPeerUnverifiedException) {
          // e.g. a certificate pinning error.
          return false
        }
        // An example of one we might want to retry with a different route is a problem connecting to a
        // proxy and would manifest as a standard IOException. Unless it is one we know we should not
        // retry, we return true and try a new route.
        return true
      }
    

    在最简单的情况下,如果我们还没有开始发送请求,那么我们知道重试必须是安全的。同样,某些响应代码(例如 408)表明服务器尚未开始任何工作,因此我们可以重试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-28
      • 2019-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-16
      • 2023-01-31
      相关资源
      最近更新 更多