Дублировать запросы от HttpClient

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

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

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

Solutions Collecting From Web of "Дублировать запросы от HttpClient"

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

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

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

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

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

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

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

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

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

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

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

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

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

С ЗАПРОСОМ VOLLEY

StringRequest.setRetryPolicy (новый DefaultRetryPolicy (0, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); volleySingleton.addToRequestQueue (stringRequest);