我正在使用带有 RxJava 和 Retrofit 2 的 Okhttp 2.5、2.6、2.7。我在调用 okhttp 时遇到了一些神秘问题。当我通过改造拨打电话时,我的 Okhttp 拦截器立即被调用,而 NetworkInterceptor 在 4 到 5 秒后调用。有时超过 15 秒,并导致 SocketTimeoutExcpetion。
请建议,我应该怎么做才能解决这个问题。是否有任何线程阻止我的调用被执行?
OkHttp 的行为应有尽有。ASocketTimeoutException
发生在服务器响应时间比客户端愿意等待的时间长时,它就放弃了。自 OkHttp 2.5(包括新的 3.0)以来,默认读取超时为 10 秒,这可以解释为什么您在 15 秒后收到异常。
您可以设置自己的超时时间,以让您的服务器有足够的时间响应:
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(20, TimeUnit.SECONDS); // connect timeout
client.setReadTimeout(20, TimeUnit.SECONDS); // socket timeout
请注意,这不会处理x
异常,如果客户端现在在几秒钟内没有收到响应,它仍然会被抛出。我会确保真正捕捉到异常。这将是您的重试逻辑的合适位置。
由于您将 RxJava 与 Retrofit 一起使用,因此您可以添加retry/retryWhen
到您的链中以捕获和处理SocketTimeoutException
错误,甚至可以混合使用指数退避。
我知道这是一个古老的故事,但我似乎找到了解决方案。要修复SocketTimeoutException,您需要设置具有 0 个(!)空闲连接的连接池!
okBuilder.connectionPool(new ConnectionPool(0, 30, TimeUnit.SECONDS));