http connection timeout issues
Asked Answered
S

10

17

I'm running into an issue when i try to use the HttpClient connecting to a url. The http connection is taking a longer time to timeout, even after i set a connection timeoout.

int timeoutConnection = 5000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);

int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

It works perfect most of the time. However, every once in while, the http connection runs for ever and ignore the setconnectiontimeout, especailly when the phone is connected to wifi, and the phone was idling.

So after the phone is idling, the first time i try to connect, the http connection ignores the setconnectiontimeout and runs forever, after i cancel it and try again, it works like charm everytime. But that one time that doesn't work it creates a threadtimeout error, i tried using a different thread, it works, but i know that the thread is running for long time.

I understand that the wifi goes to sleep on idle, but i dont understand why its ignoring the setconnectiontimeout.

Anyone can help, id really appreciated.

Stood answered 2/1, 2011 at 9:13 Comment(2)
What platform are you talking about?Antoninaantonino
The HTTP connection might "ignore" its timeout because it genuinely thinks it's connected, e.g. the initial handshake succeeded but nothing more comes out of the pipe (or in your case, the air). Maybe your phone has a tendency to keep accepting connections but immediately forgetting about them when idle. Capturing and examining the individual frames exchanged before this problem occurs will probably tell a lot more.Grillage
O
9

Not sure if this helps you, however I think it's worth sharing here. While playing with the timeout stuff I found there is a third timeout type you can assign:

// the timeout until a connection is established
private static final int CONNECTION_TIMEOUT = 5000; /* 5 seconds */

// the timeout for waiting for data
private static final int SOCKET_TIMEOUT = 5000; /* 5 seconds */

// ----------- this is the one I am talking about:
// the timeout until a ManagedClientConnection is got 
// from ClientConnectionRequest
private static final long MCC_TIMEOUT = 5000; /* 5 seconds */

...

HttpGet httpGet = new HttpGet(url);
setTimeouts(httpGet.getParams());

...

private static void setTimeouts(HttpParams params) {
    params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 
        CONNECTION_TIMEOUT);
    params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, SOCKET_TIMEOUT);
    params.setLongParameter(ConnManagerPNames.TIMEOUT, MCC_TIMEOUT);
}
Overspill answered 2/1, 2011 at 11:50 Comment(2)
Android 2.01.First of all, thank you guys for your help.@Arhimed, i tried that, it didn't work thanks though. The problem only happens under one of these conditions: 1 - if my phone is connected to wifi, and the wifi has no internet access. the timeout is not being catched in this case and it takes about 30 seconds. 2_ if the phone is connected to wifi and the wifi has internet access. After the phone has been idling for atleast 2 minutes, the initail connection takes about 30 seconds to timeout. Every other attempt, works perfectly.Stood
@Mark: if your app behaves the same as the native YouTube app, then I think you can sleep well (native apps are code by top pros who are able to use API as much as possible). Sometimes there are cases that are just out of our control. Another consoling note - 30 secs is not that much if, for instance, to compare to BlackBerry where you have 2 minutes and you can not change that. ;)Overspill
D
1
Thread t=new Thread()
{
  public void run()
  {
    try 
    {
      Thread.sleep(absolutetimeout);
      httpclient.getConnectionManager().closeExpiredConnections();
      httpclient.getConnectionManager().closeIdleConnections(absolutetimeout,TimeUnit.MILLISECONDS);
      httpclient.getConnectionManager().shutdown();
      log.debug("We shutdown the connection manager!");
    }
    catch(InterruptedException e)
    {}
  }
};

t.start();
HttpResponse res= httpclient.execute(httpget);
t.interrupt();

Is that along the lines of what you all are suggesting?

I'm not exactly sure how to cancel the execute once it has started, but this seemed to work for me. I'm not sure which of the three lines in the thread did the magic, or if it was some combination of all of them.

Delatorre answered 31/3, 2011 at 18:38 Comment(1)
Actually, this doesn't seem to work either. Do I have to put the execute in its own thread, because I really don't want to do that. Is there no way to just kill it?Delatorre
L
1

I've met the same problem, I guess maybe the Android doesn't support this parameter. In my case i tested all three parameters for the ThreadSafeClientConnManager

params.setParameter( ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(20) );
params.setIntParameter( ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 200 );
params.setLongParameter( ConnManagerPNames.TIMEOUT, 10 );
ThreadSafeClientConnManager connmgr = new ThreadSafeClientConnManager( params );

The first and second worked fine, but the third didn't work as documented. No exception was thrown and the executing thread was blocked indefinitely when the DefaultHttpClient#execute() was executing.

see http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e650
"...One can ensure the connection manager does not block indefinitely in the connection request operation by setting 'http.conn-manager.timeout' to a positive value. If the connection request cannot be serviced within the given time period ConnectionPoolTimeoutException will be thrown."

Lozoya answered 21/5, 2011 at 8:17 Comment(0)
B
0

You could manage the timeouts yourself, this way you can be confident that no matter what state the connection gets in, unless you receive an acceptable response, that your timeout will fire and the http request will be aborted.

Barytone answered 2/1, 2011 at 9:37 Comment(4)
First of all, thank you guys for your help.@Arhimed, i tried that, it didn't work.Stood
I ran a test, i connected my phone to a wifi that doesn't have internet, and i clicked on you tube app. it took 30 seconds to find out that there is no connection, just like my app. It's driving me crazy, the way its ignoring the timeout connection.Stood
That's because on a wifi without access to the internet, if your URL is to a hostname and not a direct IP address, then the connection isn't even being made; all that time you're waiting is being spent trying to resolve de hostname.Jody
If Chochos is right, and I suspect he is, then Mark you could manage the DNS lookup yourself and more aggressively cache the IP if it doesn't change much. i.e. rather than using the hostname in the URI, you use the IP address from your cache.Choi
S
0

I've had similar issues with timeouts on android. To resolve it what I did was used the commands to not let the phone idle while I was attempting to establish a connection and during any reads or writes to the connection. Its probably worth a shot in this case as well.

Spirant answered 12/1, 2011 at 14:28 Comment(0)
G
0

Although I haven't seen this on the Android platform, I've seen similar things on other platforms and the solution in these cases is to manage the timeout yourself. Kick off another thread (the timeout thread) when your make your request. The timeout thread counts down the requisite time. If the timeout expires before you receive any data, the timeout thread cancels the original request and you retry with a new request. Harder to code, but at least you know it will work.

Gstring answered 18/1, 2011 at 16:10 Comment(0)
W
0

From you snippet it's not ultimately clear if you set the timeouts before calling HttpClient.executeMethod(..). So this is my guess.

Wanton answered 19/1, 2011 at 19:48 Comment(0)
J
0

Well, if you idle/multitask to another application, then your thread that is running might be stopped and destroyed. Maybe you should put the connection code inside a Service instead?:

http://developer.android.com/reference/android/os/AsyncTask.html http://developer.android.com/reference/android/app/IntentService.html

Joyejoyful answered 21/1, 2011 at 17:52 Comment(0)
U
0

How are you making the HTTP Connection? This looks like a threading issue. If you are using a background thread, then the thread may be killed along with any timeout registered. The fact that it works the next time tells me that your code will work, if you make the call in a android component and manage the WAKE_LOCK on it yourself. Anyways please post more information about the calling mechanism?

Uvulitis answered 21/1, 2011 at 18:2 Comment(0)
S
0

The problem might be in the Apache HTTP Client. See HTTPCLIENT-1098. Fixed in 4.1.2.

The timeout exception tries to reverse DNS the IP, for logging purposes. This takes an additional time until the exception is actually fired.

Schrock answered 17/11, 2013 at 13:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.