什么导致HTTP失败:java.net.SocketException:套接字关闭?

问题描述:

我使用okhttp和retrofit为我的应用程序之一,我有很多请求使用RxJava在不同的线程上工作。 有时,我在任何请求和后缀都没有请求可以在服务器上达到SocketException。什么导致HTTP失败:java.net.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(): "); 
        } 
       }); 

没有从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 

其他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 [email protected] 

订阅我想打电话给经常工作正常,但有时上面的错误是存在的,然后停止工作。 Aferwords没有请求可以到达服务器。从更新接口

@GET("/v1/app_endpoint/{keyword}/") 
Observable<Model> details(@Path("keyword") String keyword); 

以下几个辅助方法只是为了检查配置

方法如果需要什么。

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

依赖

// 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' 
+0

你有没有得到这个问题的决议?我看到使用多个异步http请求使用okhttp 3.5.0/RxJava 2/Jackson类似的随机错误。 –

+0

我可以说你只需要根据你的服务器连接/读/写时间来使用超时配置。 –

+0

当我设置连接,读写超时时,我有同样的问题,所以,我猜SocketException正在被库处理,但奇怪的是它从来没有达到任何错误,完成或接下来的方法和在我的情况下,Observable永远不会结束......任何帮助,将不胜感激。 –

就我而言,我发现我越来越是一个突如其来的意外unsubscribe()呼叫所导致HTTP FAILED: java.net.SocketException: Socket closed错误和不调用任何onCompleted()onError()onNext()回调 - 检查进行讨论并回答here

所以,为了能够处理这种情况下,只需添加:

.doOnUnsubscribe(() -> { /*handle logic here*/ }) 

Observable,也许尝试重置有一些状态,这有望将导致恢复正常活动的能力。

在我的情况下,我要求一个错误的URL获得错误ERR_CONNECTION_REFUSED