Mqtt "PubSubClient.h" non-blocking code

Why does my ESP8266 MQTT client block the rest of the code while attempting to connect, causing a delay?

I'm using the following code to connect to an MQTT broker on my ESP8266:

Serial.print("Attempting MQTT connection...");

if (client.connect(deviceID, "NAME", "PASS","sm/", 0, false, "offline")) {
  Serial.println("connected");
  client.subscribe("sm/");
} else {
  Serial.print("failed to connect to mqtt, rc=");
  Serial.println(client.state());
}

However, after the line Serial.print("Attempting MQTT connection..."); is printed, the rest of my loop code seems to block until it finishes this check unti failed to connect to mqtt, rc=-4.

It feels like it's waiting for a long time, similar if u use delay(xxxx); in the code.

Why does this happen, and how can I prevent this blocking behavior? Is there something I can do to make the connection attempt more asynchronous, allowing the rest of my code to run while it's trying to connect to MQTT?

i simulate this by starting hotspot on my phone and then pause sharing it. so esp8266 is connected to wifi but no internet connection

Please post a complete sketch that shows the problem, using code tags when you do

Since the connect is a setup related function, the library most likely waits for it, there is no need to be super fast.

this is a way to connect to mqtt ,

i can put this code in function and run if

client.connected()==0

but when i run that code it take long time and other code blocked until that finish.

How often does your sketch connect to the MQTT broker ?

this is simple question im asking it has nothing to do with other sketch.

I check if client.connected()==false and if esp8266 is connected to wifi but there is no internet or cant connect to mqtt server. it will use above code to try to connect to mqtt and if fail it give error message. its not about how often i run this code. it is about when i run the code it take few seconds to run and in that time whoole loop function is blocked same as if u use delay();

It sounds like you are connecting to MQTT in loop(). Is that what you are doing ?

Yes, but that is in setup.

i use in loop . to check if mqtt is connected and if not i try to use that code to recconect.

the problem is if mqtt is not connected and i try to recconect and lets say for some reasons (no internet or mqtt server down) it cant connect to mqtt.

while it try to connect and until i get message that device failed to connect to mqtt this time is the problem.

Have you looked at the non blocking MQTT reconnection sketch example in the IDE ?

i read somewhere that i need to use this library:

Yes, that is normal. I have similar code in my loop, if not connected then call my routine reconnect

void loop() {
  if (!client.connected()) reconnect();      // here the mqtt connection is established
void reconnect() {      // establish mqtt client connection
  while (!client.connected()){     // Loop until we're reconnected
    mqttLogger.print("Attempting MQTT connection...");      // Attempt to connect
    if (client.connect("ESP32Logger")) 
      mqttLogger.println("connected.");   // as we have a connection here, this will be the first message published to the mqtt server
    else {
      mqttLogger.print("failed, rc=");
      mqttLogger.print(client.state());
      mqttLogger.println(" try again in 5 seconds");
      delay(5000);      // Wait 5 seconds before retrying
    }
  }
}

ill try

/*
 Reconnecting MQTT example - non-blocking

 This sketch demonstrates how to keep the client connected
 using a non-blocking reconnect function. If the client loses
 its connection, it attempts to reconnect every 5 seconds
 without blocking the main loop.

*/

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>

// Update these with values suitable for your hardware/network.
byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(172, 16, 0, 100);
IPAddress server(172, 16, 0, 2);

void callback(char* topic, byte* payload, unsigned int length) {
  // handle message arrived
}

EthernetClient ethClient;
PubSubClient client(ethClient);

long lastReconnectAttempt = 0;

boolean reconnect() {
  if (client.connect("arduinoClient")) {
    // Once connected, publish an announcement...
    client.publish("outTopic","hello world");
    // ... and resubscribe
    client.subscribe("inTopic");
  }
  return client.connected();
}

void setup()
{
  client.setServer(server, 1883);
  client.setCallback(callback);

  Ethernet.begin(mac, ip);
  delay(1500);
  lastReconnectAttempt = 0;
}


void loop()
{
  if (!client.connected()) {
    long now = millis();
    if (now - lastReconnectAttempt > 5000) {
      lastReconnectAttempt = now;
      // Attempt to reconnect
      if (reconnect()) {
        lastReconnectAttempt = 0;
      }
    }
  } else {
    // Client connected

    client.loop();
  }

}

but looks like its not ok coz same logic

the problem is coz u use delay . in this time i need to check digital input if is low and high . so i cant use delay to block all code

NO, I add more delay as the connect is already blocking. In fact, I almost never see the delay(5000) unless I have some other problem that is preventing the connect call to succeed, that is why I print the client.state so I can fix the problem.
There is NO non-blocking mqtt.
Since mqtt uses wifi, you may be able to rewrite the mqtt client to use a non blocking wifi connect but since that's a board level library, it may not be possible.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.