2012-03-26 25 views
24

Necesito establecer el tiempo de espera para la solicitud Http que hacemos a un servicio (no un servicio web). Estamos usando Apache HTTP Client. He agregado estas 2 líneas de código para configurar el tiempo de espera a petición y respuesta al servicio.Usando Apache HttpClient cómo configurar el TIEMPO FUERTE en una solicitud y respuesta

HttpConnectionParams.setConnectionTimeout(params, 10000); 
HttpConnectionParams.setSoTimeout(params, 10000); 

1) Actualmente he puesto 10 segundos como el tiempo de espera ya que veo la respuesta que viene del servicio de forma casi instantánea. ¿Debo aumentar o disminuir el tiempo?

2) ¿Qué sucederá cuando la respuesta demore más de 10 segundos? ¿Lanzará una excepción y qué excepción será? ¿Hay algo más que deba agregar para establecer el tiempo de espera en el código siguiente?

public HashMap<String, Object> getJSONData(String url) throw Exception{ 
    DefaultHttpClient httpClient = new DefaultHttpClient(); 
    HttpParams params = httpClient.getParams(); 
    HttpConnectionParams.setConnectionTimeout(params, 10000); 
    HttpConnectionParams.setSoTimeout(params, 10000); 
    HttpHost proxy = new HttpHost(getProxy(), getProxyPort()); 
    ConnRouteParams.setDefaultProxy(params, proxy); 
    URI uri; 
    InputStream data = null; 
    try { 
     uri = new URI(url); 
     HttpGet method = new HttpGet(uri); 
     HttpResponse response = httpClient.execute(method); 
     data = response.getEntity().getContent(); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 
    Reader r = new InputStreamReader(data); 
    HashMap<String, Object> jsonObj = (HashMap<String, Object>) GenericJSONUtil.fromJson(r); 
    return jsonObj; 
} 

Respuesta

31

Las excepciones que verá serán ConnectTimeoutException y SocketTimeoutException. Los valores de tiempo de espera real que usa deben ser el tiempo máximo que su aplicación está dispuesta a esperar. Una nota importante sobre el tiempo de espera de lectura es que corresponde al tiempo de espera en una lectura de socket. Por lo tanto, no es el tiempo permitido para que llegue la respuesta completa, sino más bien el tiempo otorgado a la lectura de un solo socket. Entonces, si hay 4 lecturas de socket, cada una de las cuales toma 9 segundos, su tiempo total de lectura es 9 * 4 = 36 segundos.

Si desea especificar un tiempo total para que llegue la respuesta (incluidos el tiempo de conexión y el tiempo de lectura total), puede envolver la llamada en una secuencia y usar un tiempo de espera de la secuencia para eso. Por ejemplo, yo suelo hacer algo como esto:

Future<T> future = null; 
future = pool.submit(new Callable<T>() { 
    public T call() { 
     return executeImpl(url); 
    } 
}); 

try { 
    return future.get(10, TimeUnit.SECONDS); 
} 
catch (InterruptedException e) { 
    log.warn("task interrupted", name); 
} 
catch (ExecutionException e) { 
    log.error(name + " execution exception", e); 
} 
catch (TimeoutException e) { 
    log.debug("future timed out", name); 
} 

Algunas suposiciones hechas en el código anterior son los siguientes: 1) se trata de una función con un parámetro de URL, 2) que está en una clase con un nombre de variable, 3) log es una instancia de log4j, y 4) pool es un ejecutor de grupo de subprocesos. Tenga en cuenta que incluso si utiliza un tiempo de espera de subproceso, también debe especificar un tiempo de espera de conexión y socket en HttpClient, de modo que las solicitudes lentas no consuman los recursos en el grupo de subprocesos. También tenga en cuenta que utilizo un grupo de subprocesos porque normalmente los uso en un servicio web para que el grupo de subprocesos se comparta entre varios subprocesos de tomcat. Su entorno puede ser diferente, y es posible que prefiera generar un nuevo hilo para cada llamada.

Además, por lo general he visto los tiempos de espera establecidos a través de las funciones miembro de los parametros, como esta:

params.setConnectionTimeout(10000); 
params.setSoTimeout(10000); 

Pero tal funciona su sintaxis, así (no estoy seguro).

+0

¿Qué es lo que necesito configurar/agregar si tengo que permitir que llegue el tiempo de respuesta completa? – pushya

+0

¿Puede explicar qué quiere decir con 4 lecturas de socket? Si son 4 lecturas de socket, entonces habrá 4 solicitudes diferentes asociadas con esa lectura. – pushya

+2

no, la respuesta puede venir en pedazos.Si observa cualquier código de socket de nivel bajo, verá que 'read()' ocurre en un ciclo while, y el valor de retorno de 'read()' es el número de bytes leídos. No es necesario que toda la respuesta venga en una sola lectura de socket. Actualizaré mi respuesta para incluir más detalles. – Kevin

47

Supongo que muchas personas vienen aquí por el título y porque la API HttpConnectionParams está en desuso.

Utilizando una versión reciente de cliente HTTP Apache, puede establecer estos tiempos de espera usando los parámetros de solicitud:

HttpPost request = new HttpPost(url); 

RequestConfig requestConfig = RequestConfig.custom() 
    .setSocketTimeout(TIMEOUT_MILLIS) 
    .setConnectTimeout(TIMEOUT_MILLIS) 
    .setConnectionRequestTimeout(TIMEOUT_MILLIS) 
    .build(); 

request.setConfig(requestConfig); 

Como alternativa, también puede establecer esta al crear su cliente HTTP, usando la API de constructor para el Cliente HTTP, pero también necesitará construir un administrador de conexión personalizado con una configuración de socket personalizada.

El configuration example file es un recurso excelente para conocer cómo configurar Apache HTTP Client.

Cuestiones relacionadas