Как написать перехватчик для потока данных в OkHttp? - PullRequest
0 голосов
/ 03 мая 2018

Или думаете, что перехватчик для этого сценария применим?

Наше приложение использует 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
         ...
     }
}

Ответы [ 3 ]

0 голосов
/ 10 мая 2018

Попробуй это.

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();

Удачи.

0 голосов
/ 05 июля 2018

Когда возникает ECONNRESET - Connection reset by peer, почему бы вам не отменить текущий вызов в блоке перехвата и начать новый сетевой вызов для того же файла

catch (IOException e) {
         // EXCEPTION SAYS 
         // ECONNRESET - Connection reset by peer
         ...
         call.cancel();//something like this
         startDownloadingFromScratch();//new network request to start from scratch  
     }
0 голосов
/ 10 мая 2018

Вы можете написать собственный перехватчик, как показано ниже:

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

Показанный код извлечен из этой средней статьи о перехватчиках .
Вы также можете посмотреть эту библиотеку , которая реализует перехватчики попыток, но вы можете изменить ее для своего использования.

...