2012-08-09 20 views
24

Estoy intentando enviar una solicitud a mi servidor con el siguiente código. falló en la 3ª solicitud, siempre.httpclient exception "org.apache.http.conn.ConnectionPoolTimeoutException: Tiempo de espera esperando la conexión"

import java.io.InputStreamReader; 
import java.io.UnsupportedEncodingException; 
import java.nio.charset.Charset; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.HttpStatus; 
import org.apache.http.HttpVersion; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.entity.ContentType; 
import org.apache.http.entity.StringEntity; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; 
import org.apache.http.params.BasicHttpParams; 
import org.apache.http.params.CoreConnectionPNames; 
import org.apache.http.params.HttpParams; 
import org.apache.http.params.HttpProtocolParams; 
import org.json.JSONException; 
import org.json.JSONObject; 
import org.json.JSONTokener; 

public class HttpClientTest { 
    private HttpClient client; 

    public HttpClientTest() { 
     HttpParams params = new BasicHttpParams(); 
     params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15000); 
     params.setParameter(CoreConnectionPNames.SO_TIMEOUT, 15000); 

     HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
     HttpProtocolParams.setContentCharset(params, "utf-8"); 
     HttpProtocolParams.setUseExpectContinue(params, true); 
     ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(); 
     cm.setMaxTotal(100); 
     client = new DefaultHttpClient(cm, params); 

     while (true) { 
      HttpPost mPost = new HttpPost("http://myip/myservice"); 

      JSONObject json = new JSONObject(); 
      try { 
       json.put("serialNumber", "abcd"); 
      } catch (JSONException e1) { 
       e1.printStackTrace(); 
      } 
      StringEntity s = null; 
      try { 
       s = new StringEntity(json.toString()); 
      } catch (UnsupportedEncodingException e) { 
       e.printStackTrace(); 
      }    
      s.setContentEncoding("UTF-8"); 
      s.setContentType("application/json"); 
      mPost.setEntity(s); 

      JSONObject response = null; 

      System.out.println("HttpClientTest ---> send post"); 
      HttpResponse mHttpResponse; 
      try { 
       mHttpResponse = client.execute(mPost); 
       System.out.println("HttpClientTest ---> get response"); 
       if(mHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){ 
        HttpEntity entity = mHttpResponse.getEntity(); 
        ContentType contentType = ContentType.getOrDefault(entity); 
        Charset charset = contentType.getCharset(); 
        response = new JSONObject(new JSONTokener(new InputStreamReader(entity.getContent(), charset))); 

        System.out.println("HttpClientTest ---> get result:" + response.toString()); 
       } else { 
        mPost.abort(); 
        break; 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     HttpClientTest t = new HttpClientTest(); 
    } 
} 

la excepción de la siguiente manera:

org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection 
    at org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getEntryBlocking(ConnPoolByRoute.java:417) 
    at org.apache.http.impl.conn.tsccm.ConnPoolByRoute$1.getPoolEntry(ConnPoolByRoute.java:300) 
    at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager$1.getConnection(ThreadSafeClientConnManager.java:224) 
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:401) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732) 
    at com.i360r.client.takeaway.network.HttpClientTest.<init>(HttpClientTest.java:68) 
    at com.i360r.client.takeaway.network.HttpClientTest.main(HttpClientTest.java:88) 
+1

¿Puedes encontrar alguna solución para esto? – CoronaPintu

+0

¿alguien lo resolvió? –

Respuesta

22

he arreglado! agregue mPost.releaseConnection() en finally bloques.

try { 
} catch (Exception e) { 
} finally { 
    mPost.releaseConnection(); 
} 

DO paquete de actualización a 4.2.1 org.apache.httpcomponents

39

que tenía el mismo problema y me encontré con la corrección. Este tiempo de espera se debe a una fuga de conexión. En mi caso estoy usando el método httpDelete y no consumo la respuesta. En cambio, verificando el estado de la respuesta.

La solución es que la entidad de respuesta debe consumirse. Para garantizar la liberación adecuada de los recursos del sistema, se debe cerrar la secuencia de contenido asociada a la entidad.

Así que usé EntityUtils.consumeQuietly(response.getEntity());, lo que garantiza que el contenido de la entidad se consuma por completo y que la corriente de contenido, si existe, se cierre.

+1

Tuve un problema similar con Fluent HTTP Client, al ignorar la respuesta. Todavía tiene que llamar a execute(). Descartar contenido() para evitar fugas de conexión. – rrhartjr

+4

Así que es MUY molesto ... La biblioteca debería descartarlo si no lo consume ... O al menos darle una advertencia al respecto ... – nterry

2

Esto también puede ocurrir si está utilizando ApacheHttpClient con DropWizard 0.6.2, que detrás de las escenas crea una MultiThreadedHttpConnectionManager con una configuración predeterminada - y que la configuración por defecto sólo se permite 2 conexiones http concurrentes a la vez more info here.

Así que con esta configuración, si su servidor se inunde y realiza solicitudes al mismo host todo el tiempo, ¡tendrá un máximo de 2 conexiones permitidas ejecutar a la vez!

Cuestiones relacionadas