Проблемы с тайм-аутом подключения к http
У меня возникает проблема, когда я пытаюсь использовать соединение HttpClient
к URL-адресу. Http-соединение занимает больше времени до тайм-аута, даже после того, как я установил
время соединения timeout.
int timeoutConnection = 5000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
Он отлично работает большую часть времени. Однако каждый раз в то время HTTP-соединение выполняется навсегда и игнорирует setconnectiontimeout
, особенно если телефон подключен к Wi-Fi, а телефон работает на холостом ходу.
Итак, после того, как телефон работает на холостом ходу, первый раз, когда я пытаюсь подключиться, http-соединение игнорирует setconnectiontimeout
и работает навсегда, после того, как я отменил его и повторю попытку, он работает как шарм каждый раз. Но тот раз, когда это не работает, создает ошибку threadtimeout
, я пытался использовать другой поток, он работает, но я знаю, что поток работает в течение длительного времени.
Я понимаю, что Wi-Fi идет спать на холостом ходу, но я не понимаю, почему он игнорирует setconnectiontimeout
.
Любой может помочь, id действительно оценен.
Ответы
Ответ 1
Не уверен, что это вам поможет, но я думаю, что здесь стоит поделиться. Во время игры с тайм-аутом я обнаружил, что существует третий тип тайм-аута, который вы можете назначить:
// 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);
}
Ответ 2
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();
Это то, что вы предлагаете?
Я не совсем уверен, как отменить выполнение после его запуска, но это, похоже, сработало для меня. Я не уверен, какая из трех строк в потоке сделала волшебство, или если это была какая-то комбинация из всех них.
Ответ 3
Я встретил ту же проблему, возможно, Android не поддерживает этот параметр.
В моем случае я протестировал все три параметра для 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 );
Первая и вторая работали нормально, но третий не работал, как описано. Никакое исключение не было выбрано, и исполняемый поток блокировался неограниченно, когда выполнялся исполняемый файл DefaultHttpClient # execute().
см. http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e650
"... Можно гарантировать, что диспетчер соединений не будет блокировать бесконечно в операции запроса соединения, установив" http.conn-manager.timeout "на положительное значение. Если запрос на соединение не может быть обслужит в течение заданного периода времени, ConnectionPoolTimeoutException будет кинули".
Ответ 4
Вы можете самостоятельно управлять тайм-аутами, таким образом, вы можете быть уверены, что независимо от того, в каком состоянии подключается соединение, если вы не получите приемлемый ответ, что ваш тайм-аут будет срабатывать, а запрос http будет прерван.
Ответ 5
У меня были подобные проблемы с тайм-аутами на Android. Чтобы решить эту проблему, я использовал команды, чтобы не допустить простоя телефона, когда я пытался установить соединение и во время любых чтений или записи в соединение. Его, вероятно, стоит сделать и в этом случае.
Ответ 6
Хотя я не видел этого на платформе Android, я видел подобные вещи на других платформах, и решение в этих случаях - управлять таймаутом самостоятельно. Удалите другой поток (поток таймаута), когда вы сделаете свой запрос. Тайм-аут подсчитывает требуемое время. Если истечет время ожидания до получения каких-либо данных, поток таймаута отменяет исходный запрос и повторяет попытку с новым запросом. Сложнее кодировать, но по крайней мере вы знаете, что это сработает.
Ответ 7
Из вашего фрагмента не будет в конечном счете ясным, если вы установите таймауты перед вызовом HttpClient.executeMethod(..)
. Так что это моя догадка.
Ответ 8
Ну, если вы бездействуете/многозадачны для другого приложения, то ваш поток, который работает, может быть остановлен и уничтожен. Может быть, вы должны поместить код соединения внутри службы?:
http://developer.android.com/reference/android/os/AsyncTask.html
http://developer.android.com/reference/android/app/IntentService.html
Ответ 9
Как вы делаете HTTP-соединение? Это похоже на проблему с потоками. Если вы используете фоновый поток, тогда поток может быть убит вместе с любым зарегистрированным временем ожидания. Тот факт, что он работает в следующий раз, говорит мне, что ваш код будет работать, если вы сделаете вызов в компоненте android и самостоятельно управляете WAKE_LOCK. В любом случае, пожалуйста, напишите больше информации о вызывающем механизме?
Ответ 10
Проблема может быть в HTTP-клиенте Apache. См. HTTPCLIENT-1098.
Исправлено в 4.1.2.
Исключение тайм-аута пытается отменить DNS-IP для целей ведения журнала. Это занимает дополнительное время, пока исключение не будет действительно запущено.