Apache HttpClient多个轮询连接到服务器策略

Saa*_*ooq 8 java apache-httpclient-4.x

我正在为服务器设置Java客户端,我定期轮询并根据特定响应发送消息.我用于课程的策略如下:

public class PollingClient {
    private HttpClient client = getHttpClient(); // I get a DefaultHttpClient this way so it's easier to add connection manager and strategy etc to the client later
    private HttpPost httpPost = getHttpPost(); // same idea, I set headers there

    public String poll () {
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        formparams.add(new BasicNameValuePair("id", someId));

        String responseString = null;

        try {
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(formparams, "UTF-8");        
            httppost.setURI(polluri));
            httppost.setEntity(formEntity);
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();


            if (entity != null) {
                responseString = EntityUtils.toString(entity); 
            }

            EntityUtils.consume(entity);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void send(String msg) {
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        formparams.add(new BasicNameValuePair("msg", msg));
        formparams.add(new BasicNameValuePair("id", someId));

        String responseString = null;

        try {
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(formparams, "UTF-8");

            httppost.setURI(new URI(URL + "send"));
            httppost.setEntity(formEntity);

            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();


            if (entity != null) {
                responseString = EntityUtils.toString(entity); 
            }

            EntityUtils.consume(entity);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我启动一个线程,在3秒左右进行轮询.我可以根据轮询结果从主线程发送消息.代码可以正常工作,但不断给我以下两个例外,但在两者之间保持不变.

java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated.
Make sure to release the connection before allocating another one.

org.apache.http.NoHttpResponseException: The target server failed to respond.
Run Code Online (Sandbox Code Playgroud)

我可以将异常静音,但我想知道发生了什么.我无法通过Google找到任何解决方案.我试图使用内容,HttpPost在send方法中创建一个新对象,这样的东西,但到目前为止没有任何帮助.

对于这样的情况,什么是好策略.我目前keep-aliveHttpPost对象中设置标题以防万一.除此之外,我认为我没有做任何事情.我认为这与整体战略有关.我不想为每个连接创建新对象,但我也不知道建议使用什么级别的重用.谢谢你的帮助.哦..这是HttpClient 4.2.2

Vad*_*zim 1

@Saad 的回答非常有帮助,但是当我尝试使用许多并发请求加载测试单个 url 时,我遇到了延迟。

这是解决该问题的更新版本。

    DefaultHttpClient client = new DefaultHttpClient();
    ClientConnectionManager mgr = client.getConnectionManager();
    HttpParams params = client.getParams();
    int maxConnections = 100;
    params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(maxConnections));
    params.setIntParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, maxConnections);
    ThreadSafeClientConnManager conman = new ThreadSafeClientConnManager(params, mgr.getSchemeRegistry());
    client = new DefaultHttpClient(conman, params);
Run Code Online (Sandbox Code Playgroud)