OkHttp3 SocketTimeoutException (in Android app) -- How to set read timeout for asynchronous request?
Asked Answered
M

1

7

I keep getting a java.net.SocketTimeoutException when attempting an OkHttp3 asynchronous Get. This suggests that I haven't set the read timeout value high enough (I think the default is 10 seconds).

The larger question is "How to prevent this exception?" but, unless someone has a better initial strategy, my immediate question is, "How to set a read timeout value for the request?"

In my code I've used the information from the Okttp Recipes page here

Notice the first two lines of my try-catch are commented out. That's because I cannot use the kind of builder (one capable of setting a timeout value, OkHttpClient.Builder) that I need in order to add header info (Request.Builder) .

My code looks like this:

    m_client = new OkHttpClient();


    try
    {
        //OkHttpClient.Builder bldr = m_client.newBuilder();
        //bldr.readTimeout(0, TimeUnit.SECONDS);

        Request.Builder reqBuilder = new Request.Builder();

        reqBuilder.addHeader("authorization", getToken());

        Request request = reqBuilder.url("http://plusdev.kooklah.com/api/v2_1/items/get").build();

        m_client.newCall(request).enqueue(new Callback()
        {
            @Override
            public void onFailure(Call call, IOException e)
            {
                Log.i("Logit", "Inside onFailure() -- IOException: " + e.getMessage() + " ----- stack trace: " + UtilGen.exceptionToString(e));

                runOnUiThread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                       // do stuff on UI thread
                    }
                });
            }

            @Override
            public void onResponse(Call call, final Response responseIn)
            {
                try
                {
                    m_sServerResponse = responseIn.body().string();
                }
                catch (Exception ex)
                {
                    Log.i("LogIt", "          ---Inside onResponse() -- Exception occurred. ex: " + ex.toString());
                }

                runOnUiThread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        Log.i("LogIt", "          ---Inside onResponse() -- inside run().");
                        if (!m_sServerResponse.isEmpty())
                        {
                            Log.i("LogIt", "          ---Inside onResponse() -- inside run() -- Success");
                            processDownloadedAssessments(m_sServerResponse);
                        }
                    }
                });
            }
        });
    }
    catch (Exception ex)
    {
        Log.i("LogIt", "ex: " + ex.getMessage());
    }

I found a reported issue that seems directly related, here, on the okhttp github site. There's even a recommendation to set the read timeout, which as mentioned above has been commented out because I cannot figure how to bring that kind of builder to bear on an async request as described on the Recipe page.

The stack trace for my exception is below, but be aware that most of the time I don't get the exception. Stack trace:

01-19 14:04:52.192: I/LogIt(25650): Inside onFailure() -- IOException: null ----- stack trace: java.net.SocketTimeoutException
01-19 14:04:52.192: I/LogIt(25650):     at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
01-19 14:04:52.192: I/LogIt(25650):     at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
01-19 14:04:52.192: I/LogIt(25650):     at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
01-19 14:04:52.192: I/LogIt(25650):     at okio.Okio$2.read(Okio.java:138)
01-19 14:04:52.192: I/LogIt(25650):     at okio.AsyncTimeout$2.read(AsyncTimeout.java:236)
01-19 14:04:52.192: I/LogIt(25650):     at okio.RealBufferedSource.indexOf(RealBufferedSource.java:325)
01-19 14:04:52.192: I/LogIt(25650):     at okio.RealBufferedSource.indexOf(RealBufferedSource.java:314)
01-19 14:04:52.192: I/LogIt(25650):     at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:210)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http1.Http1Codec.readResponse(Http1Codec.java:191)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:132)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:54)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.RealCall$AsyncCall.execute(RealCall.java:129)
01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
01-19 14:04:52.192: I/LogIt(25650):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
01-19 14:04:52.192: I/LogIt(25650):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
01-19 14:04:52.192: I/LogIt(25650):     at java.lang.Thread.run(Thread.java:818)
Mcmullen answered 19/1, 2017 at 19:23 Comment(5)
The OkHttpClient builder and the Request builder are two different classes. You set the timeout in the OkHttpClient builder and it applies to ALL request. You set headers to the Request builder for individual requests.Oxpecker
Very true, but how to bring the former into the request after having set its timeout value(s)?Mcmullen
you execute the Request using the OkHttpClient built using the builder with the specified timeout.Oxpecker
@Oxpecker -- As mentioned in the question the Request.Builder class is required in the async call, not the OkHttpClient.Builder.Mcmullen
I have the same problem in kotlin. Can anyone help to resolve?Departmentalize
O
20

Instead of

m_client = new OkHttpClient();

you should create the client using a builder like:

m_client = new OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .writeTimeout(10, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .build();

When you create the client like this each Request executed whit this client (using m_client.newCall(...)) will use the timeouts specified in the builder.

Oxpecker answered 19/1, 2017 at 19:54 Comment(3)
I smell what you're cooking. Have to shut down for a bit, but will try this asap. May be tomorrow. Thanks.Mcmullen
That was my problem, I was not using the build() call on the OkHttpClient builder after setting its timeouts.Mcmullen
What is their correspond Exception when timeout?Neogothic

© 2022 - 2024 — McMap. All rights reserved.