Проблемы с тайм-аутом http-соединения - PullRequest
17 голосов
/ 02 января 2011

У меня возникает проблема, когда я пытаюсь использовать HttpClient для подключения к URL.Тайм-аут соединения HTTP занимает больше времени, даже после того, как я установил тайм-аут соединения.

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

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

В большинстве случаев он работает идеально.Однако время от времени http-соединение работает вечно и игнорирует setconnectiontimeout, особенно когда телефон подключен к Wi-Fi, и телефон работает на холостом ходу.

Таким образом, после того, как телефон бездействует, первыйКогда я пытаюсь подключиться, http-соединение игнорирует setconnectiontimeout и работает вечно, после того, как я отменяю его и пытаюсь повторить, оно работает как шарм каждый раз.Но тот один раз, что не работает, это создает ошибку threadtimeout, я попытался использовать другой поток, он работает, но я знаю, что поток работает в течение длительного времени.

Я понимаю, что Wi-Fiложится спать на холостом ходу, но я не понимаю, почему он игнорирует setconnectiontimeout.

Любой может помочь, я действительно признателен.

Ответы [ 10 ]

10 голосов
/ 02 января 2011

Не уверен, поможет ли это вам, однако я думаю, что здесь стоит поделиться. Во время игры с тайм-аутом, который я обнаружил, вы можете назначить третий тип тайм-аута:

// 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);
}
1 голос
/ 21 мая 2011

Я столкнулся с той же проблемой, наверное, 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 кинули «.

1 голос
/ 31 марта 2011
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();

Это то, что вы все предлагаете?

Я не совсем уверен, как отменить выполнение после его запуска, но мне показалось, что это работает. Я не уверен, какая из трех строк в этой теме сотворила магию, или это была какая-то комбинация всех из них.

0 голосов
/ 17 ноября 2013

Возможно, проблема в HTTP-клиенте Apache.См. HTTPCLIENT-1098 .Исправлено в 4.1.2.

Исключение тайм-аута пытается изменить DNS IP для целей ведения журнала.Это займет дополнительное время, пока исключение не будет фактически запущено.

0 голосов
/ 21 января 2011

Как вы делаете HTTP-соединение?Это похоже на многопоточность.Если вы используете фоновый поток, этот поток может быть уничтожен вместе с любым зарегистрированным таймаутом.Тот факт, что он работает в следующий раз, говорит мне, что ваш код будет работать, если вы сделаете вызов в компоненте Android и сами управляете им с помощью WAKE_LOCK.В любом случае, пожалуйста, опубликуйте больше информации о механизме вызова?

0 голосов
/ 21 января 2011

Ну, если вы простаиваете / многозадачны с другим приложением, то ваш работающий поток может быть остановлен и уничтожен.Может быть, вам следует вместо этого поместить код подключения в Службу?

1002 *http://developer.android.com/reference/android/os/AsyncTask.html http://developer.android.com/reference/android/app/IntentService.html
0 голосов
/ 19 января 2011

Из вашего фрагмента не совсем понятно, если вы установите тайм-ауты до вызова HttpClient.executeMethod(..).Так что это мое предположение.

0 голосов
/ 18 января 2011

Хотя я не видел этого на платформе Android, я видел подобные вещи на других платформах, и решение в этих случаях заключается в том, чтобы самостоятельно управлять временем ожидания.Начните другой поток (поток времени ожидания), когда вы сделаете запрос.Поток времени ожидания отсчитывает необходимое время.Если время ожидания истекает до того, как вы получите какие-либо данные, поток времени ожидания отменяет исходный запрос, и вы повторяете попытку с новым запросом.Труднее кодировать, но, по крайней мере, вы знаете, что это сработает.

0 голосов
/ 12 января 2011

У меня были похожие проблемы с таймаутами на Android. Чтобы решить проблему, я использовал команды, чтобы не дать телефону бездействовать, когда я пытался установить соединение и во время любых операций чтения или записи в соединение. Вероятно, и в этом случае стоит попробовать.

0 голосов
/ 02 января 2011

Вы можете сами управлять таймаутами, так что вы можете быть уверены, что независимо от того, в каком состоянии находится соединение, если вы не получите приемлемый ответ, ваш тайм-аут сработает и запрос http будет прерван.

...