Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - Periodically HttpClient timeout occurs

Hi I already asked this questions, but this time I check that method to allow all certificate is not causing issue.

I develop an app which is also on iPhone. Problem is with api requests. I setup the timeouts for all requests. Sometimes it occurs kind a breaks from 30 - 60 second. It looks like this that app does couple request and than break, all the time timeouts, after about 45 second everything ok.

I don't know if this is server issue or android.

This problem doesn't occur on iPhone with IOS 5, but also apear on IOS 4.

I check for HttpClient and also fot HttpsURLConnection.

Connection is https, also was trying directly IP address.

All request has the same problem, all request are in async tasks.

All them looks the same:

DefaultHttpClient client = new HttpSupport().getNewHttpClient();

    client.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY_HOST,AuthScope.ANY_PORT),new UsernamePasswordCredentials(user, pass));

    HttpGet httget = new HttpGet("xxxxxxxxxxxxxxxxxxxxxxx");
    httget.setHeader("Accept", "application/json");

    HttpResponse respond = null;  

    try 
    {
        respond = client.execute(httget);
    } 
    catch (ClientProtocolException e) 
    {
        Log.e(TAG,"getEvents, ClientProtocolException");
    } 
    catch (IOException e) 
    {           
        Log.e(TAG,"getEvents, IOException: " + e.getMessage());
    }

The code dor my HttpSupport class is in my prev question : Android - API Requests

It is can be the server fault? Thank you for any help.

Recently I notice that app is hang on client.execute... try to do like this: android httpclient hangs on second request to the server (connection timed out) , but is won't help. Maybe is not a api fault, but Android as it is. This app is pointing the api really often, but for the most of request everything is alright.

Still can't get rid off the 30-45 seconds of hangs up.

Today I tested again the app and I noticed that error occur only on wi-fi connection on Samsung Tablet with 3.2. On Wildfire with 2.3.7 (wi-fi and 3g) everything seems to be alright. I'm not telling that problem doesn't occur on mobile, but while I was testing I have not noticed timeouts.

like image 787
goodm Avatar asked Mar 16 '12 11:03

goodm


2 Answers

Your client has timeout's set too short - on a mobile connection you should expect up to 30 seconds to form the connection, and 30 seconds beyond that to receive a response.

Your code (via your link):

int timeoutConnection = 3000;
        HttpConnectionParams.setConnectionTimeout(params, timeoutConnection);
        // Set the default socket timeout (SO_TIMEOUT) 
        // in milliseconds which is the timeout for waiting for data.
        int timeoutSocket = 5000;
        HttpConnectionParams.setSoTimeout(params, timeoutSocket);

It is in milliseconds. So your connection timeout is 3 seconds, and response is 5 seconds.

I would make that 30000 and 60000 respectively.

Also, if you want to rule out any server issues, install a HTTP proxy like fiddler2 and use it to display each HTTP/HTTPS request and you will see each server response. You will then see if the client or server is misbehaving.

like image 135
peterept Avatar answered Sep 19 '22 00:09

peterept


I don't have a clear explanation to your problem but I have a look into your code and think there are some fault design in your code which may hide some concealed defect which developer should take care of at compile time, instead of leave them and let them leak out at runtime.

In your HttpSupport.getNewHttpClient() implementation:

public DefaultHttpClient getNewHttpClient() {
  try {
    ... ...

    ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

    return new DefaultHttpClient(ccm, params);
  } catch (Exception e) {
    return new DefaultHttpClient();
}

}

You return a HttpClient instance in both try and catch block, where the one from try block returns a robust HttpClient that aware correct protocol, credentials, etc. used to access remote HTTP server. What is the point of return another naked HttpClent in catch block when exception occurred. Exception usually means some expected error happened and should be taken care of by developer at compile time, what you did is simply ignore all useful warnings and let them leak at application run time, and even worse, without visibility to know what is happened at run time.

So the first try to identify you problem is change you code to handle exception properly, simply print out the exception stack trace and find what are the potential problems when create/initialise your HttpClient.

Another point I would like to mention is you are create/initialise HttpClient on demand, that is, create and initialize new instance of HttpClient every time you need send HTTP request, which may not related to your problem but it is inefficient IMO.

My feeling is your problem is probably related to create/initialize HttpClient in multithread environment (as you said you use AsyncTask), as HttpClient is not thread-safe. hope this helps.

like image 29
yorkw Avatar answered Sep 17 '22 00:09

yorkw