8

或者认为适用于这种情况的拦截器?

我们的应用程序使用 OkHttp 下载文件(新版本的应用程序、每日数据库等)

有时服务器会在应用程序流式传输字节时失败(顺便说一句,recvfrom 失败:ECONNRESET)

所以为了解决这个问题,我只想编写 OkHttp 重试拦截器。但这似乎适用于非流式传输的操作。

是否有解决方案(如拦截器)来处理这种情况?


为了更清楚地展示

0%===============================100%(刚开始直播)

0% === ============================100%(完成10%

0% ====== =========================100%(完成20%

0% ====== ==========================100%(ECONNRESET - 对等方重置连接

就在此时,流媒体停止了。我希望 OkHttp 的事情是识别这种情况,然后从头开始(不是从 20%)


相关代码在这里,注意注释

 Call call = client.newCall(new Request.Builder().url(url).get().build());
 Response response = call.execute();
 // PROBLEM DOES NOT OCCUR THERE
 // PROBLEM DOES NOT OCCUR THERE
 // PROBLEM DOES NOT OCCUR THERE
 if (response.code() == 200 || response.code() == 201) {
     InputStream inputStream = null;
     try {
         long downloaded = 0;
         byte[] buff = new byte[1024 * 4];
         inputStream = response.body().byteStream();
         long target = response.body().contentLength();
         while (true) {
             // EXCEPTION OCCURS THERE
             // EXCEPTION OCCURS THERE
             // EXCEPTION OCCURS THERE
             int read = inputStream.read(buff);
             if (read == -1) {
                 break;
             }
             downloaded += read;
         }
         ...
     } catch (IOException e) {
         // EXCEPTION SAYS 
         // ECONNRESET - Connection reset by peer
         ...
     }
}
4

3 回答 3

1

您可以编写一个自定义拦截器,如下所示:

OkHttp 有拦截器。您需要一个自定义拦截器,如下所示:

public class CustomResponseInterceptor implements Interceptor {

    private final String TAG = getClass().getSimpleName();

    @Override
    public Response intercept(Object object) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        if (response.code() != 200//Your error code here,) {
           //Cancel your Request here
            return something;
        }
        Log.d(TAG, "INTERCEPTED:$ " response.toString());
        return response;
    }

显示的代码摘自这篇关于 Interceptors 的 Medium 文章
您还可以查看实现重试拦截器的这个库,但您可以修改它以供您使用。

于 2018-05-10T09:06:41.713 回答
1

ECONNRESET - Connection reset by peer发生时,为什么不取消您的 catch 块中正在进行的呼叫并为同一文件启动一个新的网络呼叫

catch (IOException e) {
         // EXCEPTION SAYS 
         // ECONNRESET - Connection reset by peer
         ...
         call.cancel();//something like this
         startDownloadingFromScratch();//new network request to start from scratch  
     }
于 2018-07-05T11:10:42.280 回答
-1

尝试这个。

OkHttpClient client = new OkHttpClient();
    client.setConnectTimeout(CONNECT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
    client.setReadTimeout(READ_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
    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;
            while (!response.isSuccessful() && tryCount < 3) {

                Log.d("intercept", "Request is not successful - " + tryCount);

                tryCount++;

                // retry the request
                response = chain.proceed(request);
            }

            // otherwise just pass the original response on
            return response;
        }
    });

将此客户设置为您的改造客户。

new Retrofit.Builder()
    ...other codes
    .client(client)
    ...other codes
    .build();

祝你好运。

于 2018-05-10T12:01:00.230 回答