web-dev-qa-db-fra.com

Délai d'expiration de la connexion HTTP sur Android ne fonctionne pas

J'écris une application qui se connecte à un service Web et je ne veux pas qu'elle attende trop longtemps si elle ne parvient pas à se connecter. J'ai donc défini le connectionTimeout des httpparams. Mais cela ne semble avoir aucun effet.

Pour tester, je coupe temporairement mon WLAN. L'application essaie de se connecter pendant un certain temps (bien plus que les 3 secondes que je veux), puis lève une exception UnknownHostException.

Voici mon code:

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

    httppost = new HttpPost(URL);
    StringEntity se = new StringEntity(envelope,HTTP.UTF_8);
    httppost.setEntity(se);
    //Code stops here until UnknownHostException is thrown.
    BasicHttpResponse httpResponse = (BasicHttpResponse) httpclient.execute(httppost);

    HttpEntity entity = httpResponse.getEntity();
    return entity;

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

Quelqu'un a des idées sur ce que j'ai manqué?

42
ascu

Essayez de le faire de cette façon:

HttpPost httpPost = new HttpPost(url);
StringEntity se = new StringEntity(envelope,HTTP.UTF_8);
httpPost.setEntity(se);

HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
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 = 3000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
BasicHttpResponse httpResponse = (BasicHttpResponse)  httpClient.execute(httpPost);

HttpEntity entity = httpResponse.getEntity();
return entity;

Vous pouvez alors attraper un possible ConnectTimeoutException .

74
Cristian

Avec la solution marquée, je reçois toujours une UnknownHostException après plus de 30 secondes. Dans ce cas, l'appareil est connecté à un routeur wifi mais il n'y a pas d'accès Internet.

L'approche adoptée consistait à lancer une tâche AsyncTask qui tentera simplement de résoudre le nom d'hôte. L'appel de blocage vérifie toutes les 250 ms pour voir s'il a réussi et après 4 secondes, il annulera la tâche et reviendra.

Voici ce que j'ai fait pour le résoudre:

private boolean dnsOkay = false;
private static final int DNS_SLEEP_WAIT = 250;
private synchronized boolean resolveDns(){

    RemoteDnsCheck check = new RemoteDnsCheck();
    check.execute();
    try {
        int timeSlept = 0;
        while(!dnsOkay && timeSlept<4000){
            //Log.d("RemoteDnsCheck", "sleeping");
            Thread.sleep(DNS_SLEEP_WAIT);
            timeSlept+=DNS_SLEEP_WAIT;
            //Log.d("RemoteDnsCheck", "slept");
        }
    } catch (InterruptedException e) {

    }

    if(!dnsOkay){
        Log.d("resolveDns", "cancelling");
        check.cancel(true);
        Log.d("resolveDns", "cancelled");
    }
    return dnsOkay;
}

private class RemoteDnsCheck extends AsyncTask<Void, Void, Void>{

    @Override
    protected Void doInBackground(Void... params) {
        try {
            Log.d("RemoteDnsCheck", "starting");
            dnsOkay = false;
            InetAddress addr = InetAddress.getByName(baseServiceURL);
            if(addr!=null){
                Log.d("RemoteDnsCheck", "got addr");
                dnsOkay = true;
            }
        } catch (UnknownHostException e) {
            Log.d("RemoteDnsCheck", "UnknownHostException");
        }
        return null;
    }

}

Ensuite, chaque fois que je veux faire un appel Web, cela s'appelle au début de la fonction:

    if(!resolveDns()){
        return null;
    }
9
hooby3dfx

Voir: https://stackoverflow.com/a/20031077/2609238

Le problème peut provenir du client HTTP Apache. Voir HTTPCLIENT-1098. Corrigé dans 4.1.2.

L'exception de délai d'attente tente d'inverser DNS l'IP, à des fins de journalisation. Cela prend un temps supplémentaire jusqu'à ce que l'exception soit réellement déclenchée.

3
noam

Cette méthode fonctionne pour moi:

AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport( endpoint, 3000) ;
1
Jr.
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
0
user2198255