Проблемы с тайм-аутом подключения к 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 для целей ведения журнала. Это занимает дополнительное время, пока исключение не будет действительно запущено.