如何在OkHttp中为数据流编写重试拦截器?

时间:2018-05-03 13:44:37

标签: android okhttp okhttp3 econnreset

或者认为此场景的拦截器适用?

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

有时服务器在app流式传输字节时失败(顺便问题是,recvfrom失败:ECONNRESET)

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

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

进行更清晰的阐述

0%============================== 100%(刚开始流式传输) < / p>

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
         ...
     }
}

2 个答案:

答案 0 :(得分:1)

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

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

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;
    }

显示的代码摘自this Medium Article on Interceptors 您还可以查看实现重试拦截器的this library,但您可以修改它以供您使用。

答案 1 :(得分: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  
     }