Java için Android için HttpResponse zaman aşımı nasıl ayarlanır


333

Bağlantı durumunu kontrol etmek için aşağıdaki işlevi oluşturdum:

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());
        ...

Sunucuyu sınamak için kapattığımda, yürütme işlemi uzun süre bekler

HttpResponse response = httpClient.execute(method);

Çok uzun süre beklemekten kaçınmak için zaman aşımını nasıl ayarlayacağını bilen var mı?

Teşekkürler!

Yanıtlar:


625

Örneğimde, iki zaman aşımı ayarlandı. Bağlantı zaman aşımı süresi java.net.SocketTimeoutException: Socket is not connectedve soket zaman aşımı süresi 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);

Mevcut herhangi bir HTTPClient'in Parametrelerini ayarlamak istiyorsanız (örn. DefaultHttpClient veya AndroidHttpClient) setParams () işlevini kullanabilirsiniz .

httpClient.setParams(httpParameters);

1
@Thomas: Cevabımı usecase'iniz için bir çözümle düzenledim
kuester2000

3
Bağlantı zaman aşımına uğradığında HttpResponse ne döndürür? Şu anda HTTP isteğim yapıldığında, çağrı döndükten sonra durum kodunu kontrol ediyorum, ancak arama zaman aşımına uğradıysa bu kodu kontrol ederken bir NullPointerException alıyorum ... temel olarak, çağrı sırasında durumu nasıl idare ederim zaman aşımı olur mu? (Verilen cevabınıza çok benzer bir kod kullanıyorum)
Tim

10
@jellyfish - belgelere rağmen AndroidHttpClient yok değil DefaultHttpClient uzatmak; bunun yerine HttpClient uygular. SetParams (HttpParams) yöntemini kullanabilmek için DefaultHttpClient kullanmanız gerekir.
Ted Hopp

3
Hey çocuklar, mükemmel cevap için can atıyorum. Ancak, bağlantı zaman aşımı sırasında kullanıcılara kadeh göstermek istiyorum ... bağlantı zaman aşımına uğradığında herhangi bir şekilde tespit edebilir miyim?
Arnab Chakraborty

2
Çalışmıyor. Sony ve Moto cihazımda test ettim, hepsi sıkıştı.
thecr0w

13

İstemcideki ayarları yapmak için:

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

Bunu JellyBean'da başarıyla kullandım, ancak eski platformlarda da çalışmalıyım ....

HTH


HttpClient ile ilişkisi nedir?
Sazzad Hissain Khan

8

Jakarta'nın http istemci kitaplığını kullanıyorsanız, aşağıdaki gibi bir şey yapabilirsiniz:

        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);

5
HttpClientParams.CONNECTION_MANAGER_TIMEOUT bilinmiyor
Tawani

* _TIMEOUT paramleri için client.getParams (). SetIntParameter (..) kullanmalısınız
loafoe

Nasıl bulunur? Cihaz wifi'ye bağlı, ancak aslında wifi üzerinden elde edilen aktif veriler değil.
Ganesh Katikar


5

@ Kuester2000 yanıtının işe yaramadığını söyleyenler için, HTTP isteklerinin ilk önce bir DNS isteğiyle ana bilgisayar IP'sini bulmaya çalışın ve sonra sunucuya gerçek HTTP isteğini gerçekleştirdiğini unutmayın. DNS isteği için zaman aşımı.

Kodunuz DNS isteği için zaman aşımı olmadan çalıştıysa, bunun nedeni bir DNS sunucusuna erişebilmeniz veya Android DNS önbelleğine basmanızdır. Bu arada, cihazı yeniden başlatarak bu önbelleği temizleyebilirsiniz.

Bu kod, orijinal yanıtı, özel bir zaman aşımı ile manuel DNS araması içerecek şekilde genişletir:

//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

Kullanılan yöntem:

//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());
}   

Bu sınıf bu blog yayınından . Git ve kullanacağın açıklamaları kontrol et

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;
    }
}

1
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);

Tamamlanmamış. HttpClient ile ilişkisi nedir?
Sazzad Hissain Khan

1

Httpclient-android-4.3.5 ile bu arada HttpClient örneğini yaratabilirsiniz, iyi çalışabilir.

 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

Bir seçenek Square'den OkHttp istemcisini kullanmaktır .

Kütüphane bağımlılığını ekleyin

Build.gradle dosyasına şu satırı ekleyin:

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

x.x.xİstenen kitaplık sürümü nerede .

İstemciyi ayarlayın

Örneğin, 60 saniyelik bir zaman aşımı ayarlamak istiyorsanız, şu şekilde yapın:

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

ps: minSdkVersion'unuz 8'den büyükse kullanabilirsiniz TimeUnit.MINUTES. Yani, şunları kullanabilirsiniz:

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

Birimler hakkında daha fazla bilgi için bkz. TimeUnit .


OkHttp'nin mevcut sürümünde zaman aşımlarının farklı ayarlanması gerekir: https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/ConfigureTimeouts.java
thijsonline

1

Kullanıyorsanız HttpURLConnection, buradasetConnectTimeout() açıklandığı gibi arayın :

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

Açıklama http isteği yerine bağlantı kurmak için zaman aşımı gibi mi?
user2499800

0
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;
}

Hangi sunucuyu temsil ediyor? "8.8.8.8", 53
Junaed
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.