-
Notifications
You must be signed in to change notification settings - Fork 9.2k
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
ConnectException/ETIMEDOUT with retrofit/OkHttp #1792
Comments
Can you provide an executable test case to demonstrate the problem you're seeing? CallTest.java is a good place to start. Right now I can't tell if this is an OkHttp problem or just an expected change in your device's connectvitiy. |
@swankjesse I believe that connectivity may not be a problem, although I have created a class that gets both a WakeLock and WifiLock to ensure that these problems are diminishes. However, I will prepare a case as soon as possible. |
Weird coincidence but I was looking at similar stack traces against latest Android code. In my case (different from yours) ETIMEDOUT is thrown in the case where Socket.connect() has been called with an infinite timeout (second arg 0). There are two strange things:
However, I would interpret the ETIMEDOUT error code as the OS terminating the connection attempt "for some reason", which may be some OS-level timeout or something else. I have asked for some clarification from the Android networking folks about when ETIMEDOUT can occur and I'll get back to you if I hear anything. |
@nfuller I have also noticed timeout after about 60 seconds. I use an AMQP client to process some messages, which also keep an open connection as much as possible, and I have caught many timeout errors, connection reset, etc. First I thought it might be related to the Volta project introduced in Lollipop, as a way of eliminating the connections that consume the battery, but the same behavior happened with the locks and in different versions, and different devices (most are Asus Nexus 7 2012 ). |
I have similar problem. Network connectivity is not an issue, server is located on my laptop in the same LAN as the phone. This occures randomly on application launch and then disappears for some time (i.e. app launches and works normally).
|
hello, public class HomeActivity extends Activity implements OnButtonClikedOnHomeActivity {
public final static String TAG = "HOMEACTIVITY";
private static final String API_URL = "https://api.github.com";
private GoogleApiClient mGoogleApiClient;
private FrameLayout fragmentContainerLayout;
private TextView titleTextView;
//GPS Listener
private LocationListener gpsListener = new LocationListener() {
@Override
public void onLocationChanged(Location gpsLocation) {
SensorSample gpsSample = new SensorSample(System.currentTimeMillis(), SensorSample.TYPE_GPS, new float[]{(float) gpsLocation.getLatitude(), (float) gpsLocation.getLongitude(), gpsLocation.getAccuracy()});
Log.d(TAG, "GPS FIX !! latitude:" + gpsLocation.getLatitude() + "longitude:" + gpsLocation.getLongitude() + " precision:" + gpsLocation.getAccuracy());
if (gpsLocation.getAccuracy()<100.0f){
Log.d(TAG,"GPS Position is accurate enough. let's do it");
GetGolfPlacesAroundTask getGolfPlaces = new GetGolfPlacesAroundTask();
getGolfPlaces.execute(gpsLocation);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
fragmentContainerLayout = (FrameLayout) findViewById(R.id.fragment_container);
titleTextView = (TextView) findViewById(R.id.textView_view_title);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment activeFragment=null;
activeFragment = HomeLoadingGolfPlacesScreen.newInstance();
if (activeFragment!=null) {
fragmentTransaction.add(R.id.fragment_container, activeFragment);
}
else Log.e(TAG,"big problem with fragments");
//let's commit the change !
fragmentTransaction.commit();
}
@Override
protected void onResume() {
super.onResume();
initGoogleApiClient();
Log.d(TAG, "CHECKING Google services");
GoogleApiAvailability mGoogleApiAvailability = GoogleApiAvailability.getInstance();
int result = mGoogleApiAvailability.isGooglePlayServicesAvailable(this);
if (result!= ConnectionResult.SUCCESS){
Log.d(TAG,"PROBLEM WIth Google services, lettin Google solve it");
GooglePlayServicesUtil.getErrorDialog(result, this, 1001).show();
}
else{
Log.d(TAG, "Google services OK, let's connect to it");
try {
mGoogleApiClient.connect();
} catch (Exception e) {e.printStackTrace();}
}
}
@Override
protected void onPause() {
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
super.onPause();
}
private class GetGolfPlacesAroundTask extends AsyncTask<Location, Void, List<APINearbyResponseObject>> {
protected List<APINearbyResponseObject> doInBackground(Location... locations) {
Location loc = locations[0];
double lat = loc.getLatitude();
double longi = loc.getLongitude();
String locString = ""+lat+","+longi;
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setReadTimeout(60 * 1000, TimeUnit.MILLISECONDS);
RestAdapter restAdapter = new RestAdapter.Builder()
.setClient(new OkClient(okHttpClient))
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(API_URL)
.build();
EgullApi api = restAdapter.create(EgullApi.class);
List<APINearbyResponseObject> around = api.getGolfAround(locString);
return around;
}
protected void onPostExecute(List<APINearbyResponseObject> result) {
Log.d(TAG, "json response : "+new Gson().toJson(result));
}
}
private void initGoogleApiClient() {
if (mGoogleApiClient==null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle connectionHint) {
Log.d(TAG, "CONNECTED TO GOOGLE PLAY SERVICES: " + connectionHint);
LocationRequest mLocationRequest = new LocationRequest().setInterval(10000).setFastestInterval(2000).setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, gpsListener);
Log.d(TAG,"GPS Listener recorded");
// Now you can use the data layer API
}
@Override
public void onConnectionSuspended(int cause) {
Log.d(TAG, "CONNECTION TO GOOGLE SERVICES SUSPENDED: " + cause);
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.d(TAG, "CONNECTECTION TO GOOGLE SERVICES FAILED: " + result);
}
})
.addApi(Wearable.API)
.addApi(LocationServices.API)
.build();
Log.d(TAG, "ONCREATE : GOOGLEAPICLIENT CREATED");
}
}
private Collection<String> getNodes() {
HashSet<String> results = new HashSet<String>();
NodeApi.GetConnectedNodesResult nodes =
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
for (Node node : nodes.getNodes()) {
results.add(node.getId());
}
return results;
}
} |
To clarify the possible causes: The device's WiFi connection are configured with static IP and the first DNS server is pointing to a Windows Server 2012 (with DNS service enabled) and the second is 8.8.4.4. Anyone using a different configuration have this issues? |
@bisonfute For instance, I have tested Retrofit with OkHttpClient and HttpURLConnectionClient, both throwing errors. |
@bisonfute I also use Location detection. Maybe that's related? |
@fuwaneko I think it's not. I'm not using nothing related to location/GPS. It seems that, like me, @bisonfute is launching various requests one after another. It seems that we are exausting the sockets is some way. @bisonfute I think that you changed the value of |
@geovanisouza92 I launch a single request. |
@fuwaneko Each time the location changes, right? I'm not too familiar with these API's, and I'm not sure how often it execute the callback. |
@geovanisouza92 no, location is independent from this. It's in another part of app. I launch single request from Service to authenticate user. Until that request finishes app doesn't send any more. |
@geovanisouza92 I spoke to the Android networking folks. The 1-minute timeout is a result of the Linux /proc/sys/net/ipv4/tcp_syn_retries setting of 5 (on Android). There may be an off by 1 error here or it may be me misunderstanding the meaning of retry or the start values, but with a value of 5 you get something like: 1 + 2 + 4 + 8 + 16 + 32 = 63 Tests on a Linux desktop with a value of 6 suggest a timeout of that + 64 = 127. To the question of when else it might occur: "all TCP connections are killed with ETIMEDOUT when the IP address that they are established on is removed from the system. This usually happens when the network goes down. In L or later, Wifi goes down when wifi is switched off disconnects. Mobile goes down when it loses signal, or 30 seconds after it's replaced by a working wifi network." I appreciate it will be difficult, but if you can come up with a repro case where it happens independent of this then I can create an Android bug. |
@nfuller Thank you for the clarification! About About So, anyone know a recommended way to keep the Wifi and the connection alive for longer, or reduce the time to reconnect? |
hi all,
private static final String API_URL = "https://api.github.com";
okHttpClient.setReadTimeout(60 * 1000, TimeUnit.MILLISECONDS); Guys, I feel like I am in a deadend. Do you think there's a way I could use Retrofit in my app ? I don't understand why the problem is not happening for everyone. Thank you for your help, jn. |
@bisonfute: This question might better be asked on StackOverflow. I only responded on this issue because I happened to be looking at the network behavior of Socket on Android and it looked relevant. Also, Jesse can't take any action until he can repeat it so it usually requires some diagnosis on your part and producing a failing test case. If you're setting the read timeout on OkHttpClient and it's triggering you should see a SocketTimeoutException, not a ConnectException. I'm not really following what you're seeing right now. If it's a networking issue rather than a timeout you may want to look at all the IPs the host is resolving to. e.g. using nslookup, and seeing if your network is routing properly to each. |
Hi @nfuller, thank you for your answer ! You are totally right, I have a ConnectException, below are the retrofit logs I get. Moreover, I ran some test trying to change the socket timetout time of my client to 60s, 30s and 10s. And the ConnectException is thrown after a time that is not related at all with my client timeout. Often around 120 seconds! The code I pasted above is a good example of a sample code that is not working, I think we can say it is a failing test case, no ? If you need more info, let me know ! 08-17 18:59:52.305 27419-27459/co.egull.egullApp D/Retrofit﹕ ---> HTTP GET https://api.github.com/users/egullgolf?pos=43.6400406%2C5.6637844
08-17 18:59:52.306 27419-27459/co.egull.egullApp D/Retrofit﹕ ---> END HTTP (no body)
08-17 19:02:05.315 27419-27459/co.egull.egullApp D/Retrofit﹕ ---- ERROR https://api.github.com/users/egullgolf?pos=43.6400406%2C5.6637844
08-17 19:02:05.317 27419-27459/co.egull.egullApp D/Retrofit﹕ java.net.ConnectException: failed to connect to api.github.com/192.30.252.136 (port 443): connect failed: ETIMEDOUT (Connection timed out)
at libcore.io.IoBridge.connect(IoBridge.java:124)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:456)
at java.net.Socket.connect(Socket.java:882)
at com.squareup.okhttp.internal.Platform$Android.connectSocket(Platform.java:190)
at com.squareup.okhttp.internal.http.SocketConnector.connectRawSocket(SocketConnector.java:160)
at com.squareup.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:79)
at com.squareup.okhttp.Connection.connect(Connection.java:143)
at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:185)
at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
at com.squareup.okhttp.Call.getResponse(Call.java:273)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:230)
at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:201)
at com.squareup.okhttp.Call.execute(Call.java:81)
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 java.lang.reflect.Proxy.invoke(Proxy.java:397)
at $Proxy0.getGolfAround(Unknown Source)
at co.egull.egullApp.home.HomeActivity$GetGolfPlacesAroundTask.doInBackground(HomeActivity.java:267)
at co.egull.egullApp.home.HomeActivity$GetGolfPlacesAroundTask.doInBackground(HomeActivity.java:249)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: android.system.ErrnoException: connect failed: ETIMEDOUT (Connection timed out)
at libcore.io.Posix.connect(Native Method)
at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:111)
at libcore.io.IoBridge.connectErrno(IoBridge.java:137)
at libcore.io.IoBridge.connect(IoBridge.java:122)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:456)
at java.net.Socket.connect(Socket.java:882)
at com.squareup.okhttp.internal.Platform$Android.connectSocket(Platform.java:190)
at com.squareup.okhttp.internal.http.SocketConnector.connectRawSocket(SocketConnector.java:160)
at com.squareup.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:79)
at com.squareup.okhttp.Connection.connect(Connection.java:143)
at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:185)
at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
at com.squareup.okhttp.Call.getResponse(Call.java:273)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:230)
at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:201)
at com.squareup.okhttp.Call.execute(Call.java:81)
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 java.lang.reflect.Proxy.invoke(Proxy.java:397)
at $Proxy0.getGolfAround(Unknown Source)
at co.egull.egullApp.home.HomeActivity$GetGolfPlacesAroundTask.doInBackground(HomeActivity.java:267)
at co.egull.egullApp.home.HomeActivity$GetGolfPlacesAroundTask.doInBackground(HomeActivity.java:249)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
08-17 19:02:05.318 27419-27459/co.egull.egullApp D/Retrofit﹕ ---- END ERROR |
@bisonfute If you're seeing a ConnectException then it is a similar issue to the previous report. The conclusion will probably be the same. Either your device cannot reach the server (the host is down or something in the middle is black-holing the TCP packets), or something is happening to bring down the network connection during the connection attempt due to (e.g.) connectivity issue or device idleness. By "failing test case" it usually means "come up with a JUnit test" (hard in this case because of the network routing aspects, I suspect). What happens if you remove OkHttp / retrofit and just create a Socket to 192.30.252.136 port 443? |
Hi all, After many investigations, I think I found the root of the problem. So everyone : don't try to use retrofit or any httpClient on android wear it won't work. As an information I solved my problem developing a proxy on the phone dedicated to my network exchanges. Thank you all for your support. |
@bisonfute thanks for the info, but my app is phone and tablet only. |
Not sure what action to take here. If this is still an issue, please let me know and I'll reopen. An executable test case that demonstrates the problem would be particularly excellent! |
Related to square/retrofit#432, I'm getting some strange errors during requests.
Retrofit: 1.9.0
OkHttp: 2.2.0 and 2.4.0
Tested Android versions: 4.4.4, 5.0.2, 5.1 and 5.1.1
Stacktrace:
I read somewhere that OkHttp uses a pool of sockets to reduce the latency, and sometimes, these sockets simply "times out". To avoid this (and considering my suspicious about AP router or server bottleneck), I've included a
for loop
to retry the request another 2 times after aConnectException
, but without any results.The text was updated successfully, but these errors were encountered: