Я пишу программу Java, работающую на встроенном устройстве с пользовательским дистрибутивом Linux и использующим RESTful API. Я хочу, чтобы эта программа продолжала работать, даже если интернет-соединение прервется.
Чтобы гарантировать это, я установил указанный тайм-аут соединения, но, похоже, он работает случайным образом.
Вот мой код:
HttpURLConnection connection = null;
String query = String.format("key=%s&deviceId=%d", key, deviceId);
String response = "";
try
{
URL requestUrl = new URL(REST_API_URL + api + "/?" + query);
System.out.println("URL: " + requestUrl.toString());
if ((connection = (HttpURLConnection) requestUrl.openConnection()) == null)
{
Log.severe("Cannot open HTTP connection.", null);
}
// Set HTTP options
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "text/json");
connection.setRequestProperty("Content-Type", "text/json");
connection.setRequestProperty("Accept-Charset", CHARSET);
connection.setConnectTimeout(2000);
connection.setReadTimeout(2000);
connection.connect();
// Check if the response was OK
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
{
Log.severe("HTTP connection failed : " + connection.getResponseMessage(), null);
}
// Get the response stream
InputStream input = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
response = reader.readLine();
}
catch (IOException e)
{
Log.severe(e.getMessage(), e);
}
finally
{
if (connection != null)
{
connection.disconnect();
}
}
Проблема в том, что если я отключу Интернет, это вызовет исключение java.net.UnknownHostException через некоторое время (~ 20 секунд), что недопустимо. На самом деле тайм-аут игнорируется.
[Здесь][1] Я читал, что на некоторых устройствах Android класс HttpURLConnection может содержать ошибки. Поэтому я также попытался использовать org.apache.http.client.HttpClient, что является худшим (мне пришлось установить наполовину устаревшие пакеты с уродливым синтаксисом) и не решает мою проблему.
Вот код с современными классами:
String query = String.format("key=%s&deviceId=%d", key, deviceId);
String response = "";
try
{
// Set HTTP parameters
URI requestUri = new URI(REST_API_URL + api + "/?" + query);
System.out.println("URL: " + requestUri.toString());
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(2000)
.setConnectTimeout(2000)
.setConnectionRequestTimeout(2000)
.build();
HttpGet httpGet = new HttpGet(requestUri);
httpGet.setConfig(requestConfig);
httpGet.addHeader("Accept", "text/json");
httpGet.addHeader("Content-Type", "text/json");
// Create a client
CloseableHttpClient httpClient = HttpClients.createDefault();
// Run the HTTP request
HttpResponse httpResponse = httpClient.execute(httpGet);
// Check the response code
if (httpResponse.getStatusLine().getStatusCode() != 200)
{
Log.severe("HTTP connection failed : " + httpResponse.getStatusLine().getReasonPhrase(), null);
}
// Get the response stream
InputStreamReader input = new InputStreamReader(httpResponse.getEntity().getContent());
BufferedReader reader = new BufferedReader(input);
response = reader.readLine();
// Release the connection
httpClient.close();
}
catch (IOException | URISyntaxException e)
{
Log.severe(e.getMessage(), e);
}
Есть идеи ?
ИЗМЕНИТЬ
Я добавил параметр в файл /etc/resolv.conf, чтобы установить тайм-аут для поиска DNS, но, похоже, он тоже игнорируется.
Вот мой файл resolv.conf:
search einet.ad.eivd.ch # eth0
nameserver 10.192.22.5 # eth0
nameserver 10.192.57.10 # eth0
options timeout:1