java - closeablehttpclient - httpclient set timeout c#
Solicitud de cliente HTTP de Java con tiempo de espera definido (9)
Descubrí que establecer la configuración de tiempo de espera en HttpConnectionParams
y HttpConnectionManager
no resolvió nuestro caso. Estamos limitados a usar org.apache.commons.httpclient
versión 3.0.1.
Terminé usando un java.util.concurrent.ExecutorService
para monitorear la llamada HttpClient.executeMethod()
.
Aquí hay un ejemplo pequeño e independiente
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
/**
* @author Jeff Kirby
* @since <pre>Jun 17, 2011</pre>
*/
public class Example {
private static final String SITE = "http://some.website.com/upload";
private static final int TIME_OUT_SECS = 5;
// upload a file and return the response as a string
public String post(File file) throws IOException, InterruptedException {
final Part[] multiPart = { new FilePart("file", file.getName(), file) };
final EntityEnclosingMethod post = new PostMethod(SITE);
post.setRequestEntity(new MultipartRequestEntity(multiPart, post.getParams()));
final ExecutorService executor = Executors.newSingleThreadExecutor();
final List<Future<Integer>> futures = executor.invokeAll(Arrays.asList(new KillableHttpClient(post)), TIME_OUT_SECS, TimeUnit.SECONDS);
executor.shutdown();
if(futures.get(0).isCancelled()) {
throw new IOException(SITE + " has timed out. It has taken more than " + TIME_OUT_SECS + " seconds to respond");
}
return post.getResponseBodyAsString();
}
private static class KillableHttpClient implements Callable<Integer> {
private final EntityEnclosingMethod post;
private KillableHttpClient(EntityEnclosingMethod post) {
this.post = post;
}
public Integer call() throws Exception {
return new HttpClient().executeMethod(post);
}
}
}
Me gustaría hacer BIT (pruebas integradas) a una serie de servidores en mi nube. Necesito la solicitud para fallar en el tiempo de espera grande.
¿Cómo debería hacer esto con Java?
Probar algo como lo de abajo no parece funcionar.
public class TestNodeAliveness {
public static NodeStatus nodeBIT(String elasticIP) throws ClientProtocolException, IOException {
HttpClient client = new DefaultHttpClient();
client.getParams().setIntParameter("http.connection.timeout", 1);
HttpUriRequest request = new HttpGet("http://192.168.20.43");
HttpResponse response = client.execute(request);
System.out.println(response.toString());
return null;
}
public static void main(String[] args) throws ClientProtocolException, IOException {
nodeBIT("");
}
}
- EDITAR: Aclara qué biblioteca se está utilizando -
Estoy usando httpclient de apache, aquí está la sección relevante de pom.xml
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.0.1</version>
<type>jar</type>
</dependency>
El mencionado método con los altos más altos de Laz está en desuso desde la versión 4.3 en adelante. Por lo tanto, sería mejor utilizar el objeto de configuración de solicitud y luego construir el cliente HTTP
private CloseableHttpClient createHttpClient()
{
CloseableHttpClient httpClient;
CommonHelperFunctions helperFunctions = new CommonHelperFunctions();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(306);
cm.setDefaultMaxPerRoute(108);
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(15000)
.setSocketTimeout(15000).build();
httpClient = HttpClients.custom()
.setConnectionManager(cm)
.setDefaultRequestConfig(requestConfig).build();
return httpClient;
}
PoolingHttpClientConnectionManager es el usuario para establecer el número máximo de conexiones y el número máximo de conexiones por ruta. Lo he configurado como 306 y 108 respectivamente. Los valores predeterminados no serán suficientes para la mayoría de los casos.
Para establecer el tiempo de espera: he utilizado el objeto RequestConfig. También puede establecer la propiedad Tiempo de espera de la solicitud de conexión para configurar el tiempo de espera para esperar la conexión del Administrador de conexión.
Esto ya fue mencionado en un comentario de benvolioT arriba. Pero, creo que vale la pena una publicación de alto nivel porque seguro me hizo rascar mi cabeza. Estoy publicando esto en caso de que ayude a alguien más.
Escribí un cliente de prueba simple y el tiempo de espera de CoreConnectionPNames.CONNECTION_TIMEOUT
funciona perfectamente en ese caso. La solicitud se cancela si el servidor no responde.
Sin embargo, dentro del código del servidor que estaba intentando probar, el código idéntico nunca se agota.
Cambiar el tiempo de espera en la actividad de conexión de socket ( CoreConnectionPNames.SO_TIMEOUT
) en lugar de la conexión HTTP ( CoreConnectionPNames.CONNECTION_TIMEOUT
) me solucionó el problema.
Además, lea los documentos de Apache con cuidado: http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/params/CoreConnectionPNames.html#CONNECTION_TIMEOUT
Tenga en cuenta el bit que dice
Tenga en cuenta que este parámetro solo se puede aplicar a las conexiones que están vinculadas a una dirección local particular.
Espero que eso le salve a alguien más todos los rasguños que sufrí. ¡Eso me enseñará a no leer la documentación a fondo!
HttpParams está en desuso en la nueva biblioteca HTTPClient de Apache. El uso del código proporcionado por Laz conduce a advertencias de depreciación.
Sugiero usar RequestConfig en su instancia de HttpGet o HttpPost:
final RequestConfig params = RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(3000).build();
httpPost.setConfig(params);
Op más tarde declaró que estaban usando Apache Commons HttpClient 3.0.1
HttpClient client = new HttpClient();
client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
client.getHttpConnectionManager().getParams().setSoTimeout(5000);
Parece que está utilizando la API de HttpClient, de la que no sé nada, pero podría escribir algo similar a esto utilizando Core Java.
try {
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setRequestMethod("HEAD");
con.setConnectTimeout(5000); //set timeout to 5 seconds
return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
} catch (java.net.SocketTimeoutException e) {
return false;
} catch (java.io.IOException e) {
return false;
}
Si está utilizando Http Client versión 4.3 y superior, debería usar esto:
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30 * 1000).build();
HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
HttpConnectionParams.setSoTimeout(params, 10*60*1000);// for 10 mins i have set the timeout
También puede definir su tiempo de espera requerido.
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
...
// set the connection timeout value to 30 seconds (30000 milliseconds)
final HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
client = new DefaultHttpClient(httpParams);