Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SocketTimeoutException on Retrofit 1.9.0 + OkHttp 2.3.0 + Android 4.4.4 #1771

Closed
baoti opened this issue Jul 27, 2015 · 31 comments
Closed

SocketTimeoutException on Retrofit 1.9.0 + OkHttp 2.3.0 + Android 4.4.4 #1771

baoti opened this issue Jul 27, 2015 · 31 comments

Comments

@baoti
Copy link

baoti commented Jul 27, 2015

I'm using Retrofit 1.9.0 + OkHttp 2.3.0 + okhttp-urlconnection 2.3.0.

It works well on most android devices, but one Android 4.4.4 KTU840 phone (xiaomi - MI 4LTE).

The SocketTimeoutException often appear after one or more service calls.

Whenever the exception appeared, no more request can work well, I have to restart the application.

Is it a known bug?

When I remove okhttp-urlconnection and setup timeout of okhttp client, no help to solve it.

When I use UrlConnectionClient (provided by retrofit) instead of OkClient, it works well.

Sorry for my bad english!

Output of logcat:

07-27 16:49:36.224  30449-31180/com.xxx.xxx D/Retrofit﹕ ---> HTTP GET http://xxx.xxx.xxx.xxx/products/search
07-27 16:49:36.224  30449-31180/com.xxx.xxx D/Retrofit﹕ Accept: application/json
07-27 16:49:36.224  30449-31180/com.xxx.xxx D/Retrofit﹕ User-Agent: XXX/1.1.0.3(beta) (App) Dalvik/1.6.0 (Linux; U; Android 4.4.4; MI 4LTE MIUI/V6.3.6.0.KXECNBL)
07-27 16:49:36.224  30449-31180/com.xxx.xxx D/Retrofit﹕ ---> END HTTP (no body)
07-27 16:49:52.615  30449-31180/com.xxx.xxx D/Retrofit﹕ ---- ERROR http://xxx.xxx.xxx.xxx/products/search
07-27 16:49:52.638  30449-31180/com.xxx.xxx D/Retrofit﹕ java.net.SocketTimeoutException
            at java.net.PlainSocketImpl.read(PlainSocketImpl.java:495)
            at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
            at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
            at okio.Okio$2.read(Okio.java:137)
            at okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
            at okio.RealBufferedSource.indexOf(RealBufferedSource.java:300)
            at okio.RealBufferedSource.indexOf(RealBufferedSource.java:289)
            at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196)
            at com.squareup.okhttp.internal.http.HttpConnection.readHeaders(HttpConnection.java:219)
            at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:198)
            at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
            at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:830)
            at com.squareup.okhttp.internal.http.HttpEngine.access$200(HttpEngine.java:95)
            at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:823)
            at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:684)
            at com.squareup.okhttp.Call.getResponse(Call.java:272)
            at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:228)
            at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:199)
            at com.squareup.okhttp.Call.execute(Call.java:79)
            at retrofit.client.OkClient.execute(OkClient.java:53)
            at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
            at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
            ...
            at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:242)
            at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:51)
            at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:40)
            at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:123)
            at java.util.concurrent.FutureTask.run(FutureTask.java:234)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
            at java.lang.Thread.run(Thread.java:838)
07-27 16:49:52.639  30449-31180/com.xxx.xxx D/Retrofit﹕ ---- END ERROR

My code:

public static RestAdapter createRestAdapter(String baseUrl, ApiRequestInterceptor interceptor, Gson gson) {
    return new RestAdapter.Builder()
            .setConverter(new GsonConverter(gson))
            .setEndpoint(baseUrl)
            .setClient(createClient())
            .setRequestInterceptor(interceptor)
            .setProfiler(interceptor)
            .setErrorHandler(ApiException.ERROR_HANDLER)
            .build();
}

public static Client createClient() {
    if (isOkHttpEnabled()) {
        if (isOkHttpTimeoutEnabled()) {
            OkHttpClient client = new OkHttpClient();
            client.setConnectTimeout(15, TimeUnit.SECONDS);
            client.setReadTimeout(15, TimeUnit.SECONDS);
            client.setWriteTimeout(15, TimeUnit.SECONDS);
            return new OkClient(client);
        }
        return new OkClient();
    } else {
        return new UrlConnectionClient();
    }
}
@swankjesse
Copy link
Collaborator

Is this a bug or a legitimate timeout? Could you provide an executable test case that demonstrates the problem? There are a few tests in CallTest.java to get you started!

@baoti
Copy link
Author

baoti commented Jul 28, 2015

Sorry, I can't write that test case. It only appeared on that device.
I think the question is why does OkClient read timeout. The network and server is OK, other requests using AsyncHttpClient can work well.

07-27 16:49:36.224  30449-31180/com.xxx.xxx D/Retrofit﹕ ---> HTTP GET http://xxx.xxx.xxx.xxx/products/search
07-27 16:49:36.224  30449-31180/com.xxx.xxx D/Retrofit﹕ Accept: application/json
07-27 16:49:36.224  30449-31180/com.xxx.xxx D/Retrofit﹕ User-Agent: XXX/1.1.0.3(beta) (App) Dalvik/1.6.0 (Linux; U; Android 4.4.4; MI 4LTE MIUI/V6.3.6.0.KXECNBL)
07-27 16:49:36.224  30449-31180/com.xxx.xxx D/Retrofit﹕ ---> END HTTP (no body)
07-27 16:49:52.615  30449-31180/com.xxx.xxx D/Retrofit﹕ ---- ERROR http://xxx.xxx.xxx.xxx/products/search
07-27 16:49:52.638  30449-31180/com.xxx.xxx D/Retrofit﹕ java.net.SocketTimeoutException

@baoti
Copy link
Author

baoti commented Jul 28, 2015

Related issue:
#1518 (comment)

This can fix it:

add
android:vmSafeMode="true"
in the Android configuration file

@swankjesse
Copy link
Collaborator

Hopefully this fixes it with Okio 1.6.0: square/okio#164

@baoti
Copy link
Author

baoti commented Aug 3, 2015

Nice, fixed!

@gkarpiak
Copy link

Still experience the issue with the following setup in build.gradle:
compile 'com.squareup.okhttp:okhttp:2.5.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.5.0'
compile 'com.squareup.okio:okio:1.6.0'

android:vmSafeMode="true" didn't fix the issue

@IgorGanapolsky
Copy link

Still happens in okhttp 2.5.0 on my Lollipop device.

@JakeWharton
Copy link
Collaborator

You don't need to comment on every issue.

On Thu, Oct 22, 2015 at 4:15 PM Igor Ganapolsky notifications@github.com
wrote:

Still happens in okhttp 2.5.0 on my Lollipop device.


Reply to this email directly or view it on GitHub
#1771 (comment).

@JakeWharton
Copy link
Collaborator

It's annoying. Those subscribed to these projects don't need to get 4
emails from you with the same thing.

On Thu, Oct 22, 2015 at 4:19 PM Igor Ganapolsky notifications@github.com
wrote:

Why not?


Reply to this email directly or view it on GitHub
#1771 (comment).

@avsector
Copy link

avsector commented Dec 3, 2015

This is still happening. I am using Retrofit 1.9.0 with OkHttp 2.6.0.
I am getting this error:

retrofit.RetrofitError
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:395)
at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at retrofit.Platform$Android$2$1.run(Platform.java:142)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.net.SocketTimeoutException
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
at okio.Okio$2.read(Okio.java:139)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:306)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:300)
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196)
at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)
at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:79)
at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:909)
at com.squareup.okhttp.internal.http.HttpEngine.access$300(HttpEngine.java:93)
at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:894)
at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:748)
at com.squareup.okhttp.Call.getResponse(Call.java:277)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:234)
at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:196)
at com.squareup.okhttp.Call.execute(Call.java:79)
at retrofit.client.OkClient.execute(OkClient.java:53)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
... 7 more

My guess is that this issue is related to dead sockets. Server closes connections and client has no way to figure out that the socket is closed. OkHttp writes to the socket, and tries to read from it, hence the SocketTimeoutException.

I am experiencing this a lot on a LG G2 device. After this a number of connections fails and after about a minute or two, it starts to work. (Maybe all the sockets in the pool are closed and renewed?).
I encountered this issue on other devices, like Nexus 5, too. Exactly as I described above.
I can assure you that this is not a network connection problem, as other apps work well when this is happening. Also I can ping the endpoint from Terminal Emulator when it is happening, but connections on the app continue to fail for about 1 minute.

I used OkHttp 2.4 and 2.5, too. This issue is with me for about 6 months!
@swankjesse If there is anything I can do (maybe more debugging with extra logs?) that can pinpoint the problem, just let me know.

@IgorGanapolsky
Copy link

@mblcdr What TLS version is your server using?

@avsector
Copy link

avsector commented Dec 3, 2015

@IgorGanapolsky I suppose it is version 1. TLSv1/SSLv3.

@IgorGanapolsky
Copy link

Well I had the same problem with TLSv1.0. So that could be the root cause.

On Thu, Dec 3, 2015 at 4:57 PM, Hamid Moazzami notifications@github.com
wrote:

@IgorGanapolsky https://github.com/IgorGanapolsky I suppose it is
version 1. TLSv1/SSLv3.


Reply to this email directly or view it on GitHub
#1771 (comment).

@avsector
Copy link

avsector commented Dec 3, 2015

@IgorGanapolsky Well, I don't think that's the problem. We have a test server with no ssl, and the issue is present there, too.

@bdiegel
Copy link

bdiegel commented Dec 3, 2015

I'm also experiencing SocketTimeoutExceptions on read using OkClient. I haven't (but will try) UrlConnectionClient. No SSL on the server. We were unable to reproduce the problem with a separate API test client (not Android). Server is returning successful responses quickly so I'm not sure why the read hangs for so long (and eventually times out).

Nexus 5 - Android M
compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.squareup.okhttp:okhttp:2.6.0'

@avsector
Copy link

avsector commented Dec 5, 2015

I think this issue needs to be reopened.

@bdiegel
Copy link

bdiegel commented Dec 8, 2015

I switched to UrlConnectionClient() a few days ago. The socket timeouts have been less frequent, but do occur. Is it possible that the problem (if there is one) may not be client related but something lower level?

java.net.SocketTimeoutException
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:484)
at java.net.PlainSocketImpl.-wrap0(PlainSocketImpl.java)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
at com.android.okhttp.okio.Okio$2.read(Okio.java:135)
at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:306)
at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:300)
at com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196)
at com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)
at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:904)
at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:788)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:439)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:384)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:497)
at retrofit.client.UrlConnectionClient.readResponse(UrlConnectionClient.java:73)
at retrofit.client.UrlConnectionClient.execute(UrlConnectionClient.java:38)

@avsector
Copy link

avsector commented Dec 8, 2015

Maybe this problem is related to #2053 and also #2073

@bdiegel
Copy link

bdiegel commented Dec 8, 2015

@mblcdr thanks for the references. Is there anything I can do to determine if my issue is related to connection leaking?

@avsector
Copy link

avsector commented Dec 8, 2015

@bdiegel
Unfortunately I don't know. I guessed according to the circumstances.

@bdiegel
Copy link

bdiegel commented Dec 17, 2015

UPDATE: my issue appears to be between with this particular device (Nexus 5- 6.0) and my 5 GHz WiFi (real timeouts). I have a dual band router and have no issue when connected to the 2.4.

Also, another Nexus 5 - 6.0 works just fine on the same 5G. Suppose it may have different WiFi hardware (did not confirm). I tried a few other devices now and they work fine also.

I'll be updating to 6.0.1 next and will see if that fixes anything for this device. Cheers!

@hatpick
Copy link

hatpick commented Dec 21, 2015

I get the same exception. In my case, I turn on the airplane mode and then turn it off, and I get the timeout error.

using okhttp 2.7.0 on android 6.0.0 Nexus 5x x86 Emulator

Update: Just tested it my code on an actual device Motorola Moto X pure edition Marshmallow 6.0.0 and all looks good.

@goodlifechris
Copy link

Hi guyz how can i use synchronous connection suing retrofit android

@dkachan1941
Copy link

I solved that problem increasing writeTimeout.

OkHttpClient.Builder builder = new OkHttpClient(). builder.connectTimeout(5, TimeUnit.MINUTES); writeTimeout(5, TimeUnit.MINUTES); readTimeout(5, TimeUnit.MINUTES); okHttpClient = builder.build();

@masmil1988
Copy link

I'm still experiencing the same issue with Retrofit 2.1.0 and OkHttp 3.3.0

@c0dehunter
Copy link

Same here, issue still present.

@wheat7
Copy link

wheat7 commented Oct 24, 2018

mark

@miladr0
Copy link

miladr0 commented Oct 31, 2018

it's wired, when i use vpn on android device, it will be connect to the server and can send request and receive response but if i switch off vpn, all requests will be SocketTimeoutException . but i still can get request and response from server using postman tool.

@moshtagh
Copy link

moshtagh commented Nov 10, 2018

it's wired, when i use vpn on android device, it will be connect to the server and can send request and receive response but if i switch off vpn, all requests will be SocketTimeoutException . but i still can get request and response from server using postman tool.

I face with the same problem. Have yout fixed it?

@miladr0
Copy link

miladr0 commented Nov 10, 2018

@moshtagh i used caddy web server as reverse proxy and put my web service api behind that.
the reason why i used caddy because it will give you free auto https. yes, retrofit+ okhttp not worked until i enabled https on the server side thanks to the caddy.

@giovesoft
Copy link

Same error with com.squareup.retrofit2:retrofit:2.5.0
Solved with a sleep for old androids before the .build():

`private static OkHttpClient getNewHttpClient(int connectionTimeoutSec, int readTimeoutSec, int writeTimeoutSec) {

    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    if (SdkInfo.isDebugBuild()){
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    } else {
        interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
    }

    OkHttpClient.Builder builder = new OkHttpClient.Builder()
            .followRedirects(true)
            .followSslRedirects(true)
            .retryOnConnectionFailure(true)
            .cache(null)
            .addInterceptor(interceptor)
            .connectTimeout(connectionTimeoutSec, TimeUnit.SECONDS)
            .writeTimeout(readTimeoutSec, TimeUnit.SECONDS)
            .readTimeout(writeTimeoutSec, TimeUnit.SECONDS)
            ;

    //builder = enableLetsEncryptRootCert(enableTls12OnPreLollipop(client)).build();
    builder = enableTls12OnPreLollipop(builder);
    builder = trustAllSslCerts(builder);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
        //added this sleep for old android phones, without this sleep the OkHttpClient.Builder will ignore the connectTimeout
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    return builder.build();
}`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests