0

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
Lalit Kumar B
  • 47,486
  • 13
  • 97
  • 124
didil
  • 693
  • 8
  • 22
  • Also see http://stackoverflow.com/questions/16605784/where-check-set-timeout-when-java-net-unknownhostexception-is-thrown – Kenster Apr 10 '15 at 14:38
  • OK thanks, I added this line to my /etc/resolv.conf file at boot : options timeout:1. But it still seems to be ignored... – didil Apr 14 '15 at 07:34

0 Answers0