Arduino-esp32: HTTPClient setTimeout hasn't any effect

Created on 24 May 2018  路  15Comments  路  Source: espressif/arduino-esp32

Hardware:

Board: Lolin D32
Core Installation/update date: 24/May/2018
IDE name: Arduino IDE
Flash Frequency: 40Mhz
Upload Speed: 921600

Description:

While using the WiFiClient library, the method setTimeout() does't work. I mean, it seems always fixed to certain among (around 18seconds). The code is showed below...You can see that I call setTimeout twice to be sure to set the proper value, but still doesn't work.

The code below is reporting the library example, enriched with setTimeout() method.

Sketch:

void loop(){
// wait for WiFi connection
    if((wifiMulti.run() == WL_CONNECTED)) {

        HTTPClient http;
        http.setTimeout(1000);
        USE_SERIAL.print("[HTTP] begin...\n");
        // configure traged server and url

        http.begin("http://192.168.0.101/index.html"); //HTTP
        http.setTimeout(1000);
        USE_SERIAL.print("[HTTP] GET...\n");
        // start connection and send HTTP header
        int start=millis();
        int httpCode = http.GET();
        int end =millis();
        Serial.println(String("Effective timeout: ") + (end-start));
        // httpCode will be negative on error
        if(httpCode > 0) {
            // HTTP header has been send and Server response header has been handled
            USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);

            // file found at server
            if(httpCode == HTTP_CODE_OK) {
                String payload = http.getString();
                USE_SERIAL.println(payload);
            }
        } else {
            USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
        }

        http.end();
    }

    delay(5000);
}

Debug Messages:

[HTTP] begin...
[HTTP] GET...
Effective timeout: 18242
[HTTP] GET... failed, error: connection refused
[HTTP] begin...
[HTTP] GET...
Effective timeout: 18498
[HTTP] GET... failed, error: connection refused
stale

Most helpful comment

No, that's a little different. The setTimeout here is only for the maximum connection time when you're already connected to the server. That's why it has no effect when the server is offline and you're stuck waiting 18+ seconds for that impossible connection to be established.

The PR you linked is to set this connection timeout for WiFiClient. I just made a simple little PR to let you access this functionality via HTTPClient: https://github.com/espressif/arduino-esp32/pull/2606

Usage might be something like:

//Prepare the request
http.begin("http://192.168.0.44/index.html");
//It's a local IP so tell it to abandon after 100ms if no connection
http.setConnectTimeout(100);
//Do it
int httpCode = http.GET();
if(httpCode < 0)
{
  //This will be the code you get on connect timeout:
  if(httpCode == HTTPC_ERROR_CONNECTION_REFUSED) 
    Serial.println("Server offline :(");
}

All 15 comments

You are using a method that I tried and did not work and it does not seem to be a timeout problem.
Try something like the following:
`//#include

include

const char* ssid = "Skynet";
const char* password = "xxx";
const char* host = "192.168.66.104";
const char* protStr = "http://";

int jd = 1234567;
char *area = "Area01";
char type = 'h';
int value = 1;
boolean okFlag = true;
int counter=0,httpCode;

String url, payload;

void setup(){
Serial.begin(115200);
// Start by connecting to a WiFi network
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
zap();

for (int i=0;i<1001;i++){
if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status
url = protStr;
url += host;
url += "/esp32/insert.php?";
url += "jd=";
url += jd;
url += "&area=";
url += area;
url += "&type=";
url += 'h';
url += "&value=";
url += value;
value++;

HTTPClient http;
http.begin(url);                                              //Specify the URL
httpCode = http.GET();
payload = http.getString();      
Serial.print(httpCode);
Serial.print(", ");
Serial.print(value);
Serial.print(", ");
Serial.println(payload);                                        //Make the request
if (httpCode > 0) { //Check for the returning code
  counter++;
} else {
  okFlag = false;
}    
http.end(); //Free the resources    

if(counter>1000 && okFlag == true){
  zap();
}

}
}
}

void zap(){
HTTPClient http;
url = protStr;
url += host;
url += "/esp32/delete.php";
http.begin(url); //Specify the URL
httpCode = http.GET();
counter = 0;
okFlag = true;
Serial.println("Todos registros eliminados com sucesso");
http.end(); //Free the resources
}

void loop(){

}
`

The timeout is in seconds. I don't think you mean 1000 seconds.

I've just updated the esp32 firmware to the last version and still not working... Are you sure about measurement unit? In the esp8266 environment it should be in millisecond

I am certain it is seconds, but you are correct that it is not working. That timeout can only be set once a connection is established. Chicken and egg problem.

@lbernstone are you sure about HTTPClient::setTimeout being specified in seconds? In the code, it's used to set _tcpTimeout which is elsewhere compared to (millis() - lastDataTime) as well as being used to set the TCP timeout in _tcp->setTimeout(timeout)

Unless I'm very much mistaken (which is entirely possible) it looks like milliseconds to me. And if you set timeout as if in seconds, for example to 10, then http operations don't ever have a chance to complete, returning with a HTTPC_ERROR_READ_TIMEOUT error every time because it only waits 10ms.

https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/src/WiFiClient.h#L83
I'm not saying it is the right thing, just what is in the code. Since it doesn't work for the most typical case, I think it probably needs a rewrite.

The setTimeOut function in both WiFiClient AND HTTPClient is in SECONDS.

Also, the setTimeOut can only be performed after a xxx.connect(). Not before!

I learned this the hard way.

Time out is in miliseconds and it works 100%.
I use like this:
http.setTimeout(5000);
httpResponseCode = http.GET(); //Make the request

Means if httpResponseCode arrives promptly, httpResponseCode = 1, the code moves on.
Otherwise it will wait up to 5000ms before giving up and setting httpResponseCode = -1 and continue the code sequence.

That is my understanding and it works precisely like that, I tested.
Hope it helps
Paulo

I've jus tried again:

  • if address is not an ip address http.begin("http://example.com/index.html"); it works perfectly
  • if address is like http.begin("http://192.168.0.44/index.html"); (this host is down)
    the timeout takes always about 18 second

EDIT: Maybe this is the fix addressed by #2383 and already fixed

No, that's a little different. The setTimeout here is only for the maximum connection time when you're already connected to the server. That's why it has no effect when the server is offline and you're stuck waiting 18+ seconds for that impossible connection to be established.

The PR you linked is to set this connection timeout for WiFiClient. I just made a simple little PR to let you access this functionality via HTTPClient: https://github.com/espressif/arduino-esp32/pull/2606

Usage might be something like:

//Prepare the request
http.begin("http://192.168.0.44/index.html");
//It's a local IP so tell it to abandon after 100ms if no connection
http.setConnectTimeout(100);
//Do it
int httpCode = http.GET();
if(httpCode < 0)
{
  //This will be the code you get on connect timeout:
  if(httpCode == HTTPC_ERROR_CONNECTION_REFUSED) 
    Serial.println("Server offline :(");
}

Now it is clear, thanks!

@boardchuz it works.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

This stale issue has been automatically closed. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings