Android - 定期发生HttpClient超时

时间:2012-03-16 11:57:13

标签: android timeout httpclient

您好我已经问过这个问题了,但是这次我检查一下这个方法是否允许所有证书都没有引起问题。

我开发了一款同样适用于iPhone的应用。问题是api请求。我为所有请求设置了超时。有时它发生在30-60秒之间。它看起来像是应用程序确实耦合请求而不是中断,所有时间超时,大约45秒后一切都好。

我不知道这是服务器问题还是android。

在使用IOS 5的iPhone上不会出现此问题,但在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 Requests

可能是服务器故障? 谢谢你的帮助。

最近我注意到应用程序在client.execute上挂起...尝试这样做:android httpclient hangs on second request to the server (connection timed out),但是没有帮助。也许不是api错,但Android就是这样。这个应用程序经常指向api,但是对于大多数请求,一切都很好。

仍然无法摆脱30-45秒的挂机。

今天我再次测试了应用程序,我发现错误只发生在三星平板电脑3.2上的Wi-Fi连接上。在野火与2.3.7(Wi-Fi和3g)一切似乎都没问题。我不是说移动设备上没有问题,但是在测试时我没有注意到超时。

2 个答案:

答案 0 :(得分:4)

您的客户端设置的超时时间太短 - 在移动连接上,您最多需要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请求,您将看到每个服务器响应。然后,您将看到客户端或服务器是否行为不正常。

答案 1 :(得分:2)

我对你的问题没有明确的解释,但是我查看了你的代码并认为你的代码中有一些错误设计可能隐藏了一些隐藏的缺陷,开发人员应该在编译时注意这些缺陷,而不是留下它们,让它们在运行时泄漏出来。

在您的HttpSupport.getNewHttpClient()实现中:

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

    ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

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

}

您在try和catch块中返回一个HttpClient实例,其中来自try块的实例返回一个强大的HttpClient,该HttpClient知道用于访问远程HTTP服务器的正确协议,凭据等。当异常发生时,在catch块中返回另一个裸HttpClent的重点是什么。异常通常意味着发生了一些预期的错误,并且应该由开发人员在编译时处理,您所做的只是忽略所有有用的警告并让它们在应用程序运行时泄漏,更糟糕的是,没有可见性知道运行时发生了什么时间。

因此,首先尝试识别您的问题是更改代码以正确处理异常,只需打印出异常堆栈跟踪并找到创建/初始化HttpClient时可能出现的问题。

我想提一点的另一点是你是按需创建/初始化HttpClient,也就是说,每当你需要发送HTTP请求时创建和初始化HttpClient的新实例,这可能与你的问题无关,但它是低效的IMO

我的感觉是你的问题可能与在多线程环境中创建/初始化HttpClient有关(正如你所说的那样使用AsyncTask),因为HttpClient不是线程安全的。希望这有帮助。