来自HttpClient的重复请求

dan*_*anb 8 android httpclient

我正在使用Android上的HttpClient 4.0.1 ...我发出一个POST请求,其头标设置为当前的毫米...我看到该请求在几毫米(5-10)内相互击中服务器两次.但我设置的标题对于两个请求都是相同的.这种情况非常偶然发生......我看到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;
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*nto 19

所以这里似乎发生的是你的客户端发送请求,没有及时得到响应,结果再次重试相同的请求(应该如此).反过来,这会导致多个POST请求被发送到您的服务器(几乎连续),您的服务器当前无法正确处理.

要验证/调试此问题,请尝试禁用HTTP重试,如下所示:

defaultHttpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler
                                             (0, false));
Run Code Online (Sandbox Code Playgroud)

这当然会处理您的重复请求问题,但随后会引入另一个更严重的问题; 也就是说,它会尝试一次(也只会一次)并失败.根据您从评论中获得的信息,您可以尝试以下几个想法:

请使用伪代码,因为我没有关于客户端架构的所有细节

连续处理多个POSTS

  • 禁用自动重试(如上所述)
  • 环绕你POST的要求类似于如何循环这个实施
  • 然后sleep手动重试之间或实现指数退避的版本

无论如何,您的服务器需要以合理的方式处理重复请求的能力,这是HTTP的后续.但是,你至少有机会在重复轰炸之前处理第一个.

我建议第一处理请求时,它需要一个步骤是设置某种形式的一个(一式两份)的标志.然后,如果/当它收到一个欺骗,它继续处理第一个请求(像往常一样)并默默地忽略欺骗.

总而言之,整个方案的重点是让您的服务器有机会设置欺骗标志.之后,根据需要丢弃(或处理)重复请求是您服务器的工作.这一切都有意义吗?