Android - периодически происходит таймаут HttpClient - PullRequest
5 голосов
/ 16 марта 2012

Привет, я уже задавал эти вопросы, но на этот раз я проверяю, что этот метод, позволяющий разрешить все сертификаты, не вызывает проблем.

Я разрабатываю приложение, которое также есть на iPhone.Проблема с запросами API.Я устанавливаю таймауты для всех запросов.Иногда это происходит с перерывами от 30 до 60 секунд.Похоже, что приложение выполняет запрос пары, а затем прерывается, все время ожидания, примерно через 45 секунд, все в порядке.

Я не знаю, является ли это проблемой с сервером или Android.

Эта проблема не возникает на iPhone с IOS 5, но также появляется на IOS 4.

Я проверяю на HttpClient и также на HttpsURLConnection.

Соединение https, также пытался напрямую IP-адрес.

Все запросы имеют одинаковую проблему, все запросы в асинхронных задачах.

Все они выглядят одинаково:

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());
    }

Код моего класса HttpSupport в моем предыдущем вопросе: Android - API-запросы

Itэто может быть ошибка сервера?Спасибо за любую помощь.

Недавно я заметил, что приложение зависло на client.execute ... попробуйте сделать так: android httpclient зависает при втором запросе к серверу (истекло время ожидания соединения) , но это не поможет.Может быть, это не ошибка API, но Android как есть.Это приложение очень часто указывает API, но по большей части все в порядке.

Все еще не могу избавиться от 30-45 секунд зависания.

Сегодня я снова протестировал приложение и заметил, что ошибка возникает только при подключении Wi-Fi на Samsung Tablet с 3.2.На Wildfire с 2.3.7 (вай фай и 3g) все вроде бы нормально.Я не говорю, что проблема не возникает на мобильном телефоне, но во время тестирования я не заметил таймаутов.

Ответы [ 2 ]

4 голосов
/ 19 марта 2012

У вашего клиента слишком короткое время ожидания - на мобильном соединении вы должны ожидать до 30 секунд, чтобы сформировать соединение, и 30 секунд после этого, чтобы получить ответ.

Ваш код (по вашей ссылке):

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);

Это в миллисекундах. Таким образом, время ожидания вашего соединения составляет 3 секунды, а ответ - 5 секунд.

Я бы сделал эти 30000 и 60000 соответственно.

Кроме того, если вы хотите исключить какие-либо проблемы с сервером, установите HTTP-прокси, например fiddler2 , и используйте его для отображения каждого запроса HTTP / HTTPS, и вы увидите каждый ответ сервера. Затем вы увидите, неправильно ли работает клиент или сервер.

2 голосов
/ 21 марта 2012

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

В вашей реализации HttpSupport.getNewHttpClient ():

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

    ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

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

}

Вы возвращаете экземпляр HttpClient в обеих попытках иблок catch, где блок из try возвращает надежный HttpClient, который знает правильный протокол, учетные данные и т. д., используемый для доступа к удаленному HTTP-серверу.Какова точка возврата другого голого HttpClent в блоке catch при возникновении исключения.Исключение обычно означает, что произошла некоторая ожидаемая ошибка, и разработчик должен позаботиться о ней во время компиляции. Вы просто проигнорировали все полезные предупреждения и позволили им просочиться во время выполнения приложения, а еще хуже - без возможности видеть, что происходит во время выполнения.время.

Итак, первая попытка идентифицировать вашу проблему - изменить код для правильной обработки исключения, просто распечатать трассировку стека исключений и найти потенциальные проблемы при создании / инициализации HttpClient.

Еще один момент, о котором я хотел бы упомянуть: вы создаете / инициализируете HttpClient по требованию, то есть создаете и инициализируете новый экземпляр HttpClient каждый раз, когда вам нужно отправить HTTP-запрос, который может не относиться к вашей проблеме, но это неэффективный IMO.

Мне кажется, ваша проблема, вероятно, связана с созданием / инициализацией HttpClient в многопоточной среде (как вы сказали, вы используете AsyncTask), так как HttpClient не является поточно-ориентированным.надеюсь, это поможет.

...