【问题标题】:Does OkHttpClient have a max retry countOkHttpClient 是否有最大重试次数
【发布时间】:2019-04-18 00:14:22
【问题描述】:

我正在为 OkHttpClient 设置连接失败重试选项。

client = new OkHttpClient();
client.setRetryOnConnectionFailure(true);

我想知道它会继续尝试多少次。查看source code 我没有看到任何最大限​​制。如何配置客户端在尝试几次后停止尝试?

【问题讨论】:

  • 源代码链接现已断开
  • 顺便说一句,setRetryOnConnectionFailure 的默认值为 true,因此您无需显式将其设置为 true(冗余)

标签: android okhttp okhttp3


【解决方案1】:

这里有更多文档https://square.github.io/okhttp/3.x/okhttp/okhttp3/OkHttpClient.Builder.html#retryOnConnectionFailure-boolean-

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

  • 无法访问的 IP 地址。如果 URL 的主机有多个 IP 地址,则无法访问任何单个 IP 地址不会导致整个请求失败。这可以提高多宿主服务的可用性。
  • 过时的池连接。 ConnectionPool 重用套接字以减少请求延迟,但这些连接有时会超时。

  • 无法访问代理服务器。 ProxySelector 可用于依次尝试多个代理服务器,最终退回到直接连接。

将此设置为 false 以避免在这样做具有破坏性时重试请求。在这种情况下,调用应用程序应自行恢复连接故障。

但一般来说,我认为它旨在在存在现有过时连接或可以重试的替代路径时重试。不要无限期地重试完全相同的事情。

另见 ConnectionSpecSelector.connectionFailed

【讨论】:

  • 这也是我的理解。此外,它还会重试失败的 SSL 握手。但它似乎不会重试彻底的 TCP 连接失败。
【解决方案2】:

我在下面做了一个解决方法:

@Override
public Response intercept(Chain chain) throws IOException {
  Request request = chain.request();
  // try the request
  Response response = doRequest(chain,request);
  int tryCount = 0;
  while (response == null && tryCount <= RetryCount) {
    String url = request.url().toString();
    url = switchServer(url);
    Request newRequest = request.newBuilder().url(url).build();
    tryCount++;
    // retry the request
    response = doRequest(chain,newRequest);
  }
  if(response == null){//important ,should throw an exception here
      throw new IOException();
  }
  return response;
}

private Response doRequest(Chain chain,Request request){
  Response response = null;
  try{
      response = chain.proceed(request);
  }catch (Exception e){
  }
  return response;
}

【讨论】:

    【解决方案3】:

    没有内置方法来设置最大限制,但您可以添加如下拦截器。

    client.interceptors().add(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
    
            // try the request
            Response response = chain.proceed(request);
    
            int tryCount = 0;
            int maxLimit = 3; //Set your max limit here
    
            while (!response.isSuccessful() && tryCount < maxLimit) {
    
                Log.d("intercept", "Request failed - " + tryCount);
    
                tryCount++;
    
                // retry the request
                response = chain.proceed(request);
            }
    
            // otherwise just pass the original response on
            return response;
        }
    });
    

    有关拦截器的更多详细信息,请参阅here

    【讨论】:

    • response.isSuccessful() 检查 HTTP 状态代码。这对连接失败有用吗?
    • 是的。如果响应码是 2xx 或 3xx,isSuccessful() 将返回 true。休息时,它将返回false。而且连接失败大多是4xx,所以应该可以的。
    • TCP连接失败意味着无法发送HTTP请求或获得响应。我不确定状态码是 4xx。
    • RajV 说得对,chain.proceed(request) 在连接失败时会抛出 IOE 异常而不是返回 false,所以 Prera​​k Sola 的回答只能在连接成功时重试
    • 我认为这段代码可能会抛出错误,首先关闭响应然后发出新请求。
    【解决方案4】:

    根据RetryAndFollowUpInterceptor的源代码是20

      /**
       * How many redirects and auth challenges should we attempt? Chrome follows 21 redirects; Firefox,
       * curl, and wget follow 20; Safari follows 16; and HTTP/1.0 recommends 5.
       */
      private static final int MAX_FOLLOW_UPS = 20;
    

    【讨论】:

      【解决方案5】:

      OkHttp 可能会“积极”地在缓慢/不可靠的连接上重复您的请求,直到它成功。这是为 GET、POST 或任何其他类型的请求完成的

      【讨论】:

        猜你喜欢
        • 2016-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多