pubsubclient: connect function stucks when network is lost

Hi, I was testing a case where network is lost on my esp32 project. While I was testing I simply turn off the router then open it after some time.

The problem occurs when a mqtt client tries to connect. I turned off the network just before the mqtt client tries to connect. The blocked segment is given below:

if (WiFi.isConnected())
   {
    WiFiClient _mqttPubClient;

    PubSubClient mqttPubClient(mqttServer, mqttPort, mqttPubCallback, _mqttPubClient);
    // WIFI connection is cut
    // WORKS UP TO HERE!
    if (mqttPubClient.connect("MyPubClient"))
    {
      // DOES NOT ENTER HERE, DEBUG LOGS SHOWS STA_DISCONNECTED here
      DEBUG_UART.printf("INFO [PERIODIC_STATE_UPDATER] State publisher connected!\r\n\r\n");

      int publishStatus = mqttPubClient.publish("DEVICE_STATE", jsonState.c_str());
      DEBUG_UART.printf("INFO [PERIODIC_STATE_UPDATER] Mqtt publish status: %d\r\n\r\n", publishStatus);
      if (publishStatus == 1)
        return true;
      else
        return false;
    }
    else
    {
     // DOES NOT ENTER HERE TO
      DEBUG_UART.printf("ERROR [PERIODIC_STATE_UPDATER] Mqtt Publisher cannot connect to the server!");
      return false;
    }
    mqttPubClient.disconnect();
  }
  else
    return false;

The program remains stuck until the watchdog is triggered. I cannot solve the problem.

Please check if there is a timeout or not for that. Thanks in advance 😃

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 4
  • Comments: 22 (1 by maintainers)

Most upvoted comments

I did some alteration to my code, to listen to WiFiEvents and handling disconnect there. This resolved the issue. Once the WiFi connection is back, pubsubclient resumes the connection and able to connect to server.

Sample WiFiEvent handling for reference.

#include <WiFi.h>
const char* ssid="ssid"
const char* password="password"
static volatile bool wifi_connected = false;

void WiFiEvent(WiFiEvent_t event)
{
  switch (event)
  {
  case SYSTEM_EVENT_AP_START:
    //can set ap hostname here
    WiFi.softAPsetHostname(_node_name.c_str());
    //enable ap ipv6 here
    WiFi.softAPenableIpV6();
    break;

  case SYSTEM_EVENT_STA_START:
    //set sta hostname here
    WiFi.setHostname(_node_name.c_str());
    break;
  case SYSTEM_EVENT_STA_CONNECTED:
    //enable sta ipv6 here
    WiFi.enableIpV6();
    break;
  case SYSTEM_EVENT_AP_STA_GOT_IP6:
    //both interfaces get the same event
    Serial.print("STA IPv6: ");
    Serial.println(WiFi.localIPv6());
    Serial.print("AP IPv6: ");
    Serial.println(WiFi.softAPIPv6());
    break;
  case SYSTEM_EVENT_STA_GOT_IP:
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    wifi_connected = true;
    break;
  case SYSTEM_EVENT_STA_DISCONNECTED:
    wifi_connected = false;
    Serial.println("STA Disconnected");
    delay(1000);
    WiFi.begin(ssid, password);
    break;
  }
}

void setup()
{
  WiFi.onEvent(WiFiEvent);
  WiFi.begin(ssid, password);
}

void loop() {
  if(wifi_connected) {
    wifi_connected_loop();
  } else {
    wifi_not_connected_loop();
  }
}

void wifi_connected_loop() {
//Do something here
}

void wifi_not_connected_loop() {
//Do something else here
}

This issue can be closed and may be the sample code can be updated with WiFiEvents rather than blocking while loop.