72

With OkHttp library, application is facing following SocketTimeoutException issue. If request size is less, then it is working fine(Less than 1MB). I am getting this exception within 10 seconds, even my socket timeout(readTimeout) value is much higher. It is consistently failing for a request(Size is 1.8MB). When I executed a request with HttpUrlConnection it is working fine. What could be a possible reason of failure?

   03-29 12:16:38.997 32066-4018/com.mobile W/System.err: java.net.SocketTimeoutException: timeout
    03-29 12:16:38.997 32066-4018/com.mobile W/System.err:     at okio.Okio$3.newTimeoutException(Okio.java:207)
    03-29 12:16:38.997 32066-4018/com.mobile W/System.err:     at okio.AsyncTimeout.exit(AsyncTimeout.java:261)
    03-29 12:16:38.997 32066-4018/com.mobile W/System.err:     at okio.AsyncTimeout$1.write(AsyncTimeout.java:158)
    03-29 12:16:38.997 32066-4018/com.mobile W/System.err:     at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:176)
    03-29 12:16:38.997 32066-4018/com.mobile W/System.err:     at okio.RealBufferedSink.write(RealBufferedSink.java:46)
    03-29 12:16:38.997 32066-4018/com.mobile W/System.err:     at okhttp3.internal.http.Http1xStream$FixedLengthSink.write(Http1xStream.java:286)
    03-29 12:16:38.997 32066-4018/com.mobile W/System.err:     at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:176)
    03-29 12:16:38.997 32066-4018/com.mobile W/System.err:     at okio.RealBufferedSink.write(RealBufferedSink.java:96)
    03-29 12:16:38.997 32066-4018/com.mobile W/System.err:     at okhttp3.RequestBody$2.writeTo(RequestBody.java:96)
    03-29 12:16:38.997 32066-4018/com.mobile W/System.err:     at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:704)
    03-29 12:16:38.997 32066-4018/com.mobile W/System.err:     at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:563)
    03-29 12:16:38.997 32066-4018/com.mobile W/System.err:     at okhttp3.RealCall.getResponse(RealCall.java:241)
    03-29 12:16:38.997 32066-4018/com.mobile W/System.err:     at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err:     at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err:     at okhttp3.RealCall.execute(RealCall.java:57)
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err:     at com.mobizio.api.BaseApi.sendOkHttpRequest(BaseApi.java:81)
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err:     at com.mobizio.api.BaseApi.doInBackground(BaseApi.java:45)
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err:     at com.mobizio.api.BaseApi.doInBackground(BaseApi.java:30)
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:292)
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err:     at java.lang.Thread.run(Thread.java:818)
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err: Caused by: java.net.SocketException: socket is closed
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err:     at com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:759)
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err:     at okio.Okio$1.write(Okio.java:80)
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err:     at okio.AsyncTimeout$1.write(AsyncTimeout.java:155)
    03-29 12:16:38.998 32066-4018/com.mobile W/System.err:  ... 20 more
Rainmaker
  • 10,294
  • 9
  • 54
  • 89
Vivek
  • 4,170
  • 6
  • 36
  • 50

9 Answers9

69

For OkHttp 3 the default value for OkHttp is 10 seconds. You can increase the timeout to 30 seconds.

OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(30, TimeUnit.SECONDS); // connect timeout
client.setReadTimeout(30, TimeUnit.SECONDS);    // socket timeout
Krish
  • 3,860
  • 1
  • 19
  • 32
  • 2
    I already set the connection timeout value to 30 seconds and socket timeout value to 15 minutes. Still I am facing the same issue and app is getting above exception within 10 seconds – Vivek Apr 07 '16 at 04:13
  • @Vivek did you find a solution? – DBragion Aug 07 '16 at 04:03
  • 2
    @DBragion As per documentation provided by Square https://github.com/square/okhttp/wiki/Recipes. It is suggested that don't use this post string method if request size is more that 1MiB. You can fallback to HttpUrlConnection method or you need to implement post streaming at described in the document. – Vivek Aug 09 '16 at 11:45
  • 2
    @Vivek -- did you ever find a solution? I'm experiencing something similar. – Alyoshak Dec 16 '16 at 17:52
  • 2
    No implemente post streaming or use httpurlconnection – Vivek Dec 17 '16 at 05:26
  • 1
    I have set to 5 min Still Im getting this issue – Bhavesh Hirpara Oct 30 '17 at 06:57
58

I solved that problem increasing writeTimeout().

Try:

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(5, TimeUnit.MINUTES) // connect timeout
.writeTimeout(5, TimeUnit.MINUTES) // write timeout
.readTimeout(5, TimeUnit.MINUTES); // read timeout

okHttpClient = builder.build();
Rainmaker
  • 10,294
  • 9
  • 54
  • 89
21

this resolved my problem:

OkHttpClient innerClient = new OkHttpClient.Builder()
            .connectTimeout(5, TimeUnit.MINUTES) // connect timeout
            .writeTimeout(5, TimeUnit.MINUTES) // write timeout
            .readTimeout(5, TimeUnit.MINUTES) // read timeout
            .build();
ronin_99
  • 309
  • 2
  • 8
8

You need to understand that only adding this won't solve your problem:

OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)

If you are using Kotlin + Retrofit + Coroutines then just use try and catch for network operations like,

viewModelScope.launch(Dispatchers.IO) {
        try {
            val userListResponseModel = apiEndPointsInterface.usersList()
            returnusersList(userListResponseModel)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

Where, Exception is type of kotlin and not of java.lang

This will handle every exception like,

  1. HttpException
  2. SocketTimeoutException
  3. FATAL EXCEPTION: DefaultDispatcher etc

Here is my usersList() function

@GET(AppConstants.APIEndPoints.HOME_CONTENT)
suspend fun usersList(): UserListResponseModel
Kishan Solanki
  • 13,761
  • 4
  • 85
  • 82
7

Use this for Kotlin

 val client1 = OkHttpClient.Builder()
                .connectTimeout(2, TimeUnit.MINUTES)
                .writeTimeout(2, TimeUnit.MINUTES) // write timeout
                .readTimeout(2, TimeUnit.MINUTES) // read timeout
                .addInterceptor(
                    BasicAuthInterceptor(
                        AmvaccAppConstants.AUTHENTICATE_USER_NAME, AmvaccAppConstants.AUTHENTICATE_USER_PASSWORD
                    )
                )
                .addInterceptor(interceptor)
                .build()
Pawan Soni
  • 860
  • 8
  • 19
2
If you are using Retrofit and Kotlin then use following code:
    var BASE_URL:String="Your URL"
    val clientSetup = OkHttpClient.Builder()
        .connectTimeout(1, TimeUnit.MINUTES)
        .writeTimeout(1, TimeUnit.MINUTES) // write timeout
        .readTimeout(1, TimeUnit.MINUTES) // read timeout
        .build()

    val getClientApi: ApiInterface
        get() {
            var retrofit: Retrofit =  Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .client(clientSetup)
                .build()
        }
Syed Hasnain
  • 130
  • 1
  • 8
  • This one helped me but can you please tell what is default time set for timeout? and is there any other clean method to avoid this problem? – Gulab Sagevadiya Feb 01 '22 at 13:03
0

In my case adding ping interval to OkHttp helps a lot in reducing number of SocketTimeoutExceptions in the app.

OkHttpClient.Builder()
        .pingInterval(3, SECONDS)
        .build()

but i am not sure if these timeouts were related to request size. I mentioned it also in this issue on github reported to OkHttp library

lukjar
  • 7,220
  • 2
  • 31
  • 40
-1

Run into a Run Catching

runCatching {
       service
}
 .map {
       if (it.isSuccessful && it.body() != null) {
           Success(Unit)
       } else {
           Error(Failure.AuthError.error(it.errorBody()))
       }
}
 .getOrElse {
       Error(Failure.Throwable(it))
}
DavidUps
  • 366
  • 3
  • 9
-3

Check if your url is correct. This error can be because of wrong url line

kham Ham
  • 5
  • 1
  • What if server down? Then it behaves same like wrong URL as response won't be arriving from server. So setting proper URL is not the solution. – Kishan Solanki Sep 17 '21 at 05:07