web-dev-qa-db-fra.com

Comment définir le délai d'attente HttpResponse pour Android dans Java

J'ai créé la fonction suivante pour vérifier l'état de la connexion:

private void checkConnectionStatus() {
    HttpClient httpClient = new DefaultHttpClient();

    try {
      String url = "http://xxx.xxx.xxx.xxx:8000/GaitLink/"
                   + strSessionString + "/ConnectionStatus";
      Log.d("phobos", "performing get " + url);
      HttpGet method = new HttpGet(new URI(url));
      HttpResponse response = httpClient.execute(method);

      if (response != null) {
        String result = getResponse(response.getEntity());
        ...

Quand j’arrête le serveur pour tester l’exécution, attend longtemps à la ligne

HttpResponse response = httpClient.execute(method);

Est-ce que quelqu'un sait comment définir le délai d'attente afin d'éviter d'attendre trop longtemps?

Merci!

332
Niko Gamulin

Dans mon exemple, deux délais d'attente sont définis. Le délai de connexion lève Java.net.SocketTimeoutException: Socket is not connected et le socket Java.net.SocketTimeoutException: The operation timed out.

HttpGet httpGet = new HttpGet(url);
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
// The default value is zero, that means the timeout is not used. 
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT) 
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpResponse response = httpClient.execute(httpGet);

Si vous souhaitez définir les paramètres de tout HTTPClient existant (par exemple, DefaultHttpClient ou AndroidHttpClient), vous pouvez utiliser la fonction setParams ().

httpClient.setParams(httpParameters);
623
kuester2000

Pour définir les paramètres sur le client:

AndroidHttpClient client = AndroidHttpClient.newInstance("Awesome User Agent V/1.0");
HttpConnectionParams.setConnectionTimeout(client.getParams(), 3000);
HttpConnectionParams.setSoTimeout(client.getParams(), 5000);

J'ai utilisé cela avec succès sur JellyBean, mais je devrais aussi travailler pour les anciennes plates-formes ....

HTH

13
user484261

Si vous utilisez la bibliothèque du client http de Jakarta, vous pouvez faire quelque chose comme:

        HttpClient client = new HttpClient();
        client.getParams().setParameter(HttpClientParams.CONNECTION_MANAGER_TIMEOUT, new Long(5000));
        client.getParams().setParameter(HttpClientParams.SO_TIMEOUT, new Integer(5000));
        GetMethod method = new GetMethod("http://www.yoururl.com");
        method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, new Integer(5000));
        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
        int statuscode = client.executeMethod(method);
8
Pablo Santa Cruz

Si vous utilisez le client http par défaut, voici comment procéder à l'aide des paramètres http par défaut:

HttpClient client = new DefaultHttpClient();
HttpParams params = client.getParams();
HttpConnectionParams.setConnectionTimeout(params, 3000);
HttpConnectionParams.setSoTimeout(params, 3000);

Le crédit original va à http://www.jayway.com/2009/03/17/configuring- timeout-with-Apache-httpclient-40/

6
Learn OpenGL ES

Pour ceux qui disent que la réponse de @ kuester2000 ne fonctionne pas, n'oubliez pas que les requêtes HTTP, essayez d'abord de trouver l'adresse IP de l'hôte avec une requête DNS, puis envoyez la requête HTTP au serveur. Vous devrez donc peut-être définir un délai d'attente pour la demande DNS.

Si votre code a fonctionné sans délai pour la requête DNS, c'est parce que vous pouvez atteindre un serveur DNS ou que vous accédez au cache DNS Android. En passant, vous pouvez effacer ce cache en redémarrant le périphérique.

Ce code étend la réponse d'origine pour inclure une recherche DNS manuelle avec un délai d'expiration personnalisé:

//Our objective
String sURL = "http://www.google.com/";
int DNSTimeout = 1000;
int HTTPTimeout = 2000;

//Get the IP of the Host
URL url= null;
try {
     url = ResolveHostIP(sURL,DNSTimeout);
} catch (MalformedURLException e) {
    Log.d("INFO",e.getMessage());
}

if(url==null){
    //the DNS lookup timed out or failed.
}

//Build the request parameters
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, HTTPTimeout);
HttpConnectionParams.setSoTimeout(params, HTTPTimeout);

DefaultHttpClient client = new DefaultHttpClient(params);

HttpResponse httpResponse;
String text;
try {
    //Execute the request (here it blocks the execution until finished or a timeout)
    httpResponse = client.execute(new HttpGet(url.toString()));
} catch (IOException e) {
    //If you hit this probably the connection timed out
    Log.d("INFO",e.getMessage());
}

//If you get here everything went OK so check response code, body or whatever

Méthode utilisée:

//Run the DNS lookup manually to be able to time it out.
public static URL ResolveHostIP (String sURL, int timeout) throws MalformedURLException {
    URL url= new URL(sURL);
    //Resolve the Host IP on a new thread
    DNSResolver dnsRes = new DNSResolver(url.getHost());
    Thread t = new Thread(dnsRes);
    t.start();
    //Join the thread for some time
    try {
        t.join(timeout);
    } catch (InterruptedException e) {
        Log.d("DEBUG", "DNS lookup interrupted");
        return null;
    }

    //get the IP of the Host
    InetAddress inetAddr = dnsRes.get();
    if(inetAddr==null) {
        Log.d("DEBUG", "DNS timed out.");
        return null;
    }

    //rebuild the URL with the IP and return it
    Log.d("DEBUG", "DNS solved.");
    return new URL(url.getProtocol(),inetAddr.getHostAddress(),url.getPort(),url.getFile());
}   

Cette classe est de cet article de blog . Allez vérifier les remarques si vous allez l'utiliser.

public static class DNSResolver implements Runnable {
    private String domain;
    private InetAddress inetAddr;

    public DNSResolver(String domain) {
        this.domain = domain;
    }

    public void run() {
        try {
            InetAddress addr = InetAddress.getByName(domain);
            set(addr);
        } catch (UnknownHostException e) {
        }
    }

    public synchronized void set(InetAddress inetAddr) {
        this.inetAddr = inetAddr;
    }
    public synchronized InetAddress get() {
        return inetAddr;
    }
}
5
David Darias

vous pouvez créer une instance HttpClient en passant avec Httpclient-Android-4.3.5, cela peut bien fonctionner.

 SSLContext sslContext = SSLContexts.createSystemDefault();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext,
                SSLConnectionSocketFactory.STRICT_HOSTNAME_VERIFIER);
                RequestConfig.Builder requestConfigBuilder = RequestConfig.custom().setCircularRedirectsAllowed(false).setConnectionRequestTimeout(30*1000).setConnectTimeout(30 * 1000).setMaxRedirects(10).setSocketTimeout(60 * 1000);
        CloseableHttpClient hc = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(requestConfigBuilder.build()).build();
1
foxundermon

Si vous utilisez la HttpURLConnection, appelez setConnectTimeout() comme décrit ici :

URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(CONNECT_TIMEOUT);
1
Bruno Peres

Une option consiste à utiliser le client OkHttp , à partir de Square.

Ajoutez la dépendance de la bibliothèque

Dans le build.gradle, incluez cette ligne:

compile 'com.squareup.okhttp:okhttp:x.x.x'

x.x.x est la version de bibliothèque souhaitée.

Définir le client

Par exemple, si vous souhaitez définir un délai d'attente de 60 secondes, procédez comme suit:

final OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setReadTimeout(60, TimeUnit.SECONDS);
okHttpClient.setConnectTimeout(60, TimeUnit.SECONDS);

ps: Si votre minSdkVersion est supérieur à 8, vous pouvez utiliser TimeUnit.MINUTES. Donc, vous pouvez simplement utiliser:

okHttpClient.setReadTimeout(1, TimeUnit.MINUTES);
okHttpClient.setConnectTimeout(1, TimeUnit.MINUTES);

Pour plus de détails sur les unités, voir TimeUnit .

1
androidevil
HttpParams httpParameters = new BasicHttpParams();
            HttpProtocolParams.setVersion(httpParameters, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(httpParameters,
                    HTTP.DEFAULT_CONTENT_CHARSET);
            HttpProtocolParams.setUseExpectContinue(httpParameters, true);

            // Set the timeout in milliseconds until a connection is
            // established.
            // The default value is zero, that means the timeout is not used.
            int timeoutConnection = 35 * 1000;
            HttpConnectionParams.setConnectionTimeout(httpParameters,
                    timeoutConnection);
            // Set the default socket timeout (SO_TIMEOUT)
            // in milliseconds which is the timeout for waiting for data.
            int timeoutSocket = 30 * 1000;
            HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
1
Sandeep
public boolean isInternetWorking(){
    try {
        int timeOut = 5000;
        Socket socket = new Socket();
        SocketAddress socketAddress = new InetSocketAddress("8.8.8.8",53);
        socket.connect(socketAddress,timeOut);
        socket.close();
        return true;
    } catch (IOException e) {
        //silent
    }
    return false;
}
0
Eco4ndly