Как установить тайм-аут HttpResponse для Android в Java
Я создал следующую функцию для проверки состояния подключения:
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());
...
когда я выключаю сервер для тестирования выполнение ждет долгое время в строке
HttpResponse response = httpClient.execute(method);
кто-нибудь знает, как установить тайм-аут, чтобы не ждать слишком долго?
спасибо!
10 ответов:
в моем примере установлены два таймаута. Тайм-аут соединения выдает "java.net.SocketTimeoutException: сокет не подключен" и тайм-аут сокета "java.net.SocketTimeoutException: время ожидания операции".
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);
Если вы хотите установить параметры любого существующего HTTPClient (например, DefaultHttpClient или AndroidHttpClient), вы можете использовать функцию setParams().
httpClient.setParams(httpParameters);
для установки настроек на клиенте:
AndroidHttpClient client = AndroidHttpClient.newInstance("Awesome User Agent V/1.0"); HttpConnectionParams.setConnectionTimeout(client.getParams(), 3000); HttpConnectionParams.setSoTimeout(client.getParams(), 5000);
Я успешно использовал это на JellyBean, но также должен работать для старых платформ ....
HTH
Если вы используете Джакарту клиентская библиотека http затем вы можете сделать что-то вроде:
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);
Если вы используете http-клиент по умолчанию, вот как это сделать с помощью параметров http по умолчанию:
HttpClient client = new DefaultHttpClient(); HttpParams params = client.getParams(); HttpConnectionParams.setConnectionTimeout(params, 3000); HttpConnectionParams.setSoTimeout(params, 3000);
оригинальный кредит идет на http://www.jayway.com/2009/03/17/configuring-timeout-with-apache-httpclient-40/
для тех, кто говорит, что ответ @kuester2000 не работает, обратите внимание, что HTTP-запросы сначала пытаются найти IP-адрес хоста с DNS-запросом, а затем делают фактический HTTP-запрос на сервер, поэтому вам также может потребоваться установить тайм-аут для DNS-запроса.
Если ваш код работал без тайм-аута для запроса DNS, это потому, что вы можете добраться до DNS-сервера или вы попали в кэш DNS Android. Кстати вы можете очистить этот кэш перезагрузить устройство.
этот код расширяет исходный ответ, чтобы включить ручной поиск DNS с пользовательским таймаутом:
//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
используемый метод:
//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()); }
этот класс из этот блог. Идите и проверьте замечания, если вы будете использовать его.
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; } }
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);
вы можете создать экземпляр HttpClient кстати с Httpclient-android-4.3.5, он может хорошо работать.
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();
вариант заключается в использовании OkHttp клиента, от площади.
добавить зависимость библиотека
в построении.gradle, включите эту строку:
compile 'com.squareup.okhttp:okhttp:x.x.x'
здесь
x.x.x
- это нужные библиотеки.установить клиент
например, если вы хотите установить тайм-аут в 60 секунд, сделать так:
final OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setReadTimeout(60, TimeUnit.SECONDS); okHttpClient.setConnectTimeout(60, TimeUnit.SECONDS);
ps: Если ваш minSdkVersion больше 8, вы можете использовать
TimeUnit.MINUTES
. Таким образом, вы можете просто использовать:okHttpClient.setReadTimeout(1, TimeUnit.MINUTES); okHttpClient.setConnectTimeout(1, TimeUnit.MINUTES);
для получения более подробной информации о единицах измерения см. TimeUnit.
Если вы используете
HttpURLConnection
, называютsetConnectTimeout()
Как рассказали здесь:URL url = new URL(myurl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(CONNECT_TIMEOUT);