I'm writing a Java program running on an embedded device with a custom Linux dist and using a RESTful API. I want that this program keep going even if the Internet connection goes down.
To ensure that, I set a specified connection timeout but it seems to work randomly.
Here is my code :
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();
}
}
The problem is if I disconnect Internet, this throws an java.net.UnknownHostException after a while (~20 sec) which is unacceptable. Actually, the timeout is ignored.
[Here][1] I've read that on some Android devices, the HttpURLConnection class could be buggy. So I also tried with org.apache.http.client.HttpClient which is worst (I had to install half deprecated packages with an ugly syntax) and doesn't solve my problem.
Here is the code with up to date classes :
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);
}
Any idea ?
EDIT
I added an option to my /etc/resolv.conf file to set a timeout for DNS lookup but it seems to be ignored too.
Here is my resolv.conf file :
search einet.ad.eivd.ch # eth0
nameserver 10.192.22.5 # eth0
nameserver 10.192.57.10 # eth0
options timeout:1