是什么导致HTTP FAILED:java.net.SocketException:Socket关闭了?

Jig*_*tel 10 android rx-java okhttp retrofit2

我正在使用okhttp并对我的一个应用程序进行改造,并且我有很多请求使用RxJava在不同的线程上工作.有时我在任何请求上都有SocketException,之后没有请求可以到达服务器.

例如,我可以分享一个样本.

我可以分享的代码中很少有修改过的代码段.

Subscription details = api.details("keyword")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Model>() {
                    @Override
                    public void onCompleted() {
                        Timber.d("onCompleted(): ");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Timber.e(e, "onError(): ");
                    }

                    @Override
                    public void onNext(final Model details) {
                        Timber.d("onNext(): ");
                    }
                });
Run Code Online (Sandbox Code Playgroud)

没有任何东西从3个回调中调用.

Stackstace:

11-17 15:50:53.991 16595-10314/ D/OkHttp: --> GET API_REQUEST_URL
11-17 15:50:53.991 16595-10314/ D/OkHttp: Host: HOST_NAME
11-17 15:50:53.991 16595-10314/ D/OkHttp: Connection: Keep-Alive
11-17 15:50:53.991 16595-10314/ D/OkHttp: Accept-Encoding: gzip
11-17 15:50:53.991 16595-10314/ D/OkHttp: User-Agent: okhttp/3.4.2
11-17 15:50:53.991 16595-10314/ D/OkHttp: User-Agent: Android-App
11-17 15:50:53.991 16595-10314/ D/OkHttp: --> END GET
11-17 15:50:53.992 16595-10314/ D/OkHttp: <-- HTTP FAILED: java.net.SocketException: Socket closed
Run Code Online (Sandbox Code Playgroud)

其他IOException

11-17 16:36:04.274 28523-29137/ D/OkHttp: Host: HOST_NAME
11-17 16:36:04.274 28523-29137/ D/OkHttp: Connection: Keep-Alive
11-17 16:36:04.274 28523-29137/ D/OkHttp: Accept-Encoding: gzip
11-17 16:36:04.274 28523-29137/ D/OkHttp: User-Agent: okhttp/3.4.2
11-17 16:36:04.274 28523-29137/ D/OkHttp: User-Agent: Android-App
11-17 16:36:04.274 28523-29137/ D/OkHttp: --> END GET
11-17 16:36:04.282 28523-29137/ D/OkHttp: <-- HTTP FAILED: java.io.IOException: unexpected end of stream on okhttp3.Address@6924d4a0
Run Code Online (Sandbox Code Playgroud)

订阅我试图经常工作正常,但有时上面的错误就在那里,然后停止工作.Aferwords没有请求可以到达服务器.

改造界面的方法

@GET("/v1/app_endpoint/{keyword}/")
Observable<Model> details(@Path("keyword") String keyword);
Run Code Online (Sandbox Code Playgroud)

下面是一些帮助方法,仅用于检查配置是否需要.

public static Retrofit retrofit() {
    return provideRetrofit(provideGson(), provideOkHttpClient());
}

public static Gson provideGson() {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.addSerializationExclusionStrategy(new AnnotationExclusionStrategy());
    gsonBuilder.addDeserializationExclusionStrategy(new AnnotationExclusionStrategy());
    gsonBuilder.setExclusionStrategies(new ExclusionStrategy() {
        @Override
        public boolean shouldSkipField(FieldAttributes f) {
            return f.getDeclaringClass().equals(RealmObject.class);
        }

        @Override
        public boolean shouldSkipClass(Class<?> clazz) {
            return false;
        }
    });
    gsonBuilder.registerTypeAdapterFactory(AutoValueGsonTypeAdapterFactory.create());
    return gsonBuilder.create();
}

public static OkHttpClient provideOkHttpClient() {
    return new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(600, TimeUnit.SECONDS)
            .readTimeout(1, TimeUnit.MINUTES)
            .retryOnConnectionFailure(true)
            .addNetworkInterceptor(new Interceptor() {
                @Override
                public okhttp3.Response intercept(Chain chain) throws IOException {
                    Request newRequest = chain.request().newBuilder()
                            .addHeader("Content-Type", "application/json")
                            .addHeader("User-Agent", "Android-App")
                            .build();
                    return chain.proceed(newRequest);
                }
            })
            .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            .build();
}

public static Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) {
    return new Retrofit.Builder()
            .baseUrl(BuildConfig.API_URL)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io()))
            .build();
}
Run Code Online (Sandbox Code Playgroud)

依赖

// Networking
compile 'com.squareup.okhttp3:okhttp:3.4.2'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
Run Code Online (Sandbox Code Playgroud)

Boj*_*ski 6

就我而言,我发现我收到的是一个突然的意外unsubscribe()调用,它导致了HTTP FAILED: java.net.SocketException: Socket closed错误,并且没有调用任何onCompleted() onError()onNext()回调 - 请查看讨论并在此处回答。

因此,为了能够处理这种情况,只需添加:

.doOnUnsubscribe(() -> { /*handle logic here*/ })
Run Code Online (Sandbox Code Playgroud)

到你的Observable,也许尝试在那里重置一些状态,希望这会导致恢复正常活动的能力。