дубликаты запросов от HttpClient - PullRequest
8 голосов
/ 21 января 2012

Я использую HttpClient 4.0.1 на Android ... Я делаю запрос POST с набором заголовков, который является текущим миллис ... Я вижу, что запрос попал на сервер дважды в течение нескольких миллисдруг друга .. но заголовок, который я установил, одинаков для обоих запросов.Это происходит очень редко ... Я не вижу реальной разницы между запросами в Wireshark ... Я просто понятия не имею, как это может происходить.Кто-нибудь сталкивался с этим раньше или есть какие-либо советы о том, как его отладить?

вот код, который я использую для создания клиента:

public static HttpClient getAndroidHttpClient(final int timeOut) {
    // set up the schemas
    SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    schemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));

    // set up our params
    HttpParams params = new BasicHttpParams();
    params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeOut);
    params.setIntParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, timeOut);
    params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, timeOut);
    params.setLongParameter(ConnManagerPNames.TIMEOUT, timeOut);
    params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 1);
    params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(1));
    params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);

    HttpProtocolParams.setUserAgent(params, "android-client-v1.0");
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(params, "utf8");

    ThreadSafeClientConnManager conman = new ThreadSafeClientConnManager(params, schemeRegistry);

    DefaultHttpClient defaultHttpClient = new DefaultHttpClient(conman, params);

    return defaultHttpClient;
}

Ответы [ 3 ]

19 голосов
/ 24 января 2012

Итак, похоже, что здесь происходит то, что ваш клиент отправляет запрос, не получает ответ своевременно и в результате повторяет тот же запрос еще раз (как и должно быть).Это, в свою очередь, приводит к тому, что на ваш сервер отправляется несколько POST запросов (почти последовательно), с которыми ваш сервер в настоящее время не может справиться должным образом.

Чтобы проверить / отладить это, попробуйте отключить повтор HTTP-запросов следующим образом.:

defaultHttpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler
                                             (0, false));

Это, конечно, будет иметь дело с вашей проблемой дубликатов запросов, но затем создаст еще одну более серьезную проблему;а именно, он попытается один раз (и только один раз) и потерпит неудачу.Из информации, которую я получил из ваших комментариев, вот несколько идей, которые вы можете попробовать:

Пожалуйста, ознакомьтесь с псевдокодом, поскольку у меня нет всех деталей того, как ваш клиент спроектирован

Обработка нескольких POSTS подряд

  • Отключить автоматические повторные попытки (как указано выше)
  • Обернуть ваши POST запросы в цикл, аналогичныйкак это реализовано
  • Затем либо sleep между вашими ручными попытками или реализацией вашей версии экспоненциального отката

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

Я рекомендую сделать шаг first , который требуется выполнить при обработке запроса, чтобы установить некоторыеформа (дубликат) флаг .Затем, если / когда он получает дублирование, он продолжает обрабатывать первый запрос (как обычно) и молча игнорирует дубликаты.

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

1 голос
/ 24 января 2012

Я не могу говорить о версии HttpClient, поставляемой с Android, так как теперь это фактически форк, основанный на чрезвычайно старом снимке до BETA.Однако если вы используете стандартную версию Apache HttpClient 4.x, он НЕ автоматически повторяет запросы POST или PUT, если не настроено иное.

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

0 голосов
/ 21 июля 2017

Политика повторных попытокМы можем настроить

С ЗАПРОСОМ НА ВАЛЛИИ

stringRequest.setRetryPolicy (new DefaultRetryPolicy (0, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BO):volleySingleton.addToRequestQueue (stringRequest);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...