knolleary / pubsubclient

A client library for the Arduino Ethernet Shield that provides support for MQTT.
http://pubsubclient.knolleary.net/
MIT License
3.78k stars 1.46k forks source link

MQTT Client stuck at `mqttClient.connect("id", "user", "pass")`. No runtime error, no error code, no timeout. #991

Closed Nuddel69 closed 1 year ago

Nuddel69 commented 1 year ago

The client seems to freeze when executing mqttClient.connect(). I find it strange considering how it manages a few complete transmissions before this happens. I'm using GSM - I make sure the arduino is connected before each transmission by reconnecting and checking whether there's a valid IP-address present. There doesn't seem to be many others with this same issue so I figured I'd try my luck here. Here's the mqtt function:

  if (!mqttClient.connected()) {
    Serial.print("MQTT - Attempting to connect to MQTT broker: ");
    Serial.println(broker);

    if (!mqttClient.connect("id", "user", "pass")) {
      Serial.print("MQTT - connection failed! Error code = ");
      Serial.println(mqttClient.state());
    } else {
      Serial.println("MQTT - connected");
      send_to_mqtt();
      Serial.println("MQTT - message sent.");
      mqttClient.disconnect();  // disconnects mqtt
      gsmClient.stop();   // disconnects network
      isClientConnected = false;
      Serial.println("MQTT - mqttClient and gsmClient disconnected.");
    }
  } else {
    Serial.println("MQTT - already connected");
  }

There's a reconnect function executed before each MQTT transmission looking like this:

  checkNetwork();
  Serial.println("Reconnecting GSM...");
  GSM.getNetwork()->disconnect();
  delay(500);
  Serial.println(GSM.localIP());
  int thresh = 3;
  while(GSM.localIP() == IPAddress(0,0,0,0) && thresh > 0)
  {
    Serial.println("No Ip - Connecting...");

    switch(GSM.getNetwork()->connect())
    {
      case 0:  //NSAPI_ERROR_OK
      Serial.println("Connection established.");
      break;

      case -3020:    //NSAPI_ERROR_BUSY
      Serial.println("Asynchronous operation cannot be started. ");
      break;

      case -3015:    //NSAPI_ERROR_IS_CONNECTED
      Serial.println("Already connected.");
      break;

      default:
      Serial.println("Connection failed");
      break;
    }
    delay(1000);
    thresh--;
  } 
  if (!thresh)
  {
    Serial.println("Failed to establish GSM connection.");
    physReset(RESETpin);
  }
  else
  {
    Serial.print("GSM connected at IP adress: ");
    Serial.println(GSM.localIP());
  }

Here's a screenshot of the output:

bilde

After looking through the source code I'm guessing this is the part where I'm getting stuck (in boolean PubSubClient::connect(const char *id, const char *user, const char *pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage, boolean cleanSession)), but I can't seem to figure a way to solve it

            while (!_client->available()) {
                unsigned long t = millis();
                if (t-lastInActivity >= ((int32_t) this->socketTimeout*1000UL)) {
                    _state = MQTT_CONNECTION_TIMEOUT;
                    _client->stop();
                    return false;
                }
            }