【发布时间】:2021-03-29 03:06:03
【问题描述】:
在我的场景中,我们的后端希望为任何请求获取一个唯一 ID,但我读到“OkHttp 可能会在缓慢/不可靠的连接上‘积极地’重复您的请求,直到它成功。”来自here 和一些 OkHttp 问题。我知道我可以使用retryOnConnectionFailure(false) 禁用重试机制,但我想启用它来处理连接问题。正是我想要的是,在静默重试之前修改请求。我可以在发送静默请求之前拦截吗?
【问题讨论】:
在我的场景中,我们的后端希望为任何请求获取一个唯一 ID,但我读到“OkHttp 可能会在缓慢/不可靠的连接上‘积极地’重复您的请求,直到它成功。”来自here 和一些 OkHttp 问题。我知道我可以使用retryOnConnectionFailure(false) 禁用重试机制,但我想启用它来处理连接问题。正是我想要的是,在静默重试之前修改请求。我可以在发送静默请求之前拦截吗?
【问题讨论】:
如果您添加一个 networkInterceptor,那么您应该有大约 1:1 的调用对您的后端进行。如果您获得缓存命中,普通拦截器可能不会涉及实际请求,并且它不会看到所有重试。所以添加一个 networkInterceptor,它将为每个选择的路由调用。
多次尝试来自备用路由(多个 DNS 结果)和基于表明这样做是安全的 HTTP 请求或服务器响应代码安全地重试某些调用。
有关信息,请参阅https://square.github.io/okhttp/interceptors/。
在应用程序和网络拦截器之间进行选择
每个拦截器链都有相对的优点。
应用拦截器
Don’t need to worry about intermediate responses like redirects and retries. Are always invoked once, even if the HTTP response is served from the cache. Observe the application’s original intent. Unconcerned with OkHttp-injected headers like If-None-Match. Permitted to short-circuit and not call Chain.proceed(). Permitted to retry and make multiple calls to Chain.proceed(). Can adjust Call timeouts using withConnectTimeout, withReadTimeout, withWriteTimeout.网络拦截器
Able to operate on intermediate responses like redirects and retries. Not invoked for cached responses that short-circuit the network. Observe the data just as it will be transmitted over the network. Access to the Connection that carries the request.
【讨论】:
我认为您可以使用 Interceptor 解决此过程。当一台服务器无法连接时,您可以连接到另一台服务器。
@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;
}
【讨论】: