when MQTT broker is offline non-blocking reconnect function takes about 30 seconds.
how can I improve the sketch?
sketch example:
/*
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, 0xBE, 0xEF, 0x55, 0x55 }; //DEADBEEF5555
IPAddress ip(192, 168, 41, 28);
IPAddress server(192, 168, 41, 23);
void callback(char* topic, byte* payload, unsigned int length) {
// handle message arrived
}
EthernetClient ethClient;
PubSubClient client(ethClient);
long lastReconnectAttempt = 0;
long mqttReconnectTimeout = 5000;
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);
//袠薪懈褑懈邪谢懈蟹懈褉褍械屑 UART 写谢褟 芯褌谢邪写芯褔薪芯谐芯 胁褘胁芯写邪
Serial.begin(115200);
Ethernet.begin(mac, ip);
delay(1500);
lastReconnectAttempt = 0;
}
void loop()
{
if (!client.connected()) {
long now = millis();
if (now - lastReconnectAttempt > 5000) {
Serial.print("now-lastReconnectAttempt: "); //
Serial.println(now-lastReconnectAttempt); //
lastReconnectAttempt = now;
Serial.print("lastReconnectAttempt: "); //
Serial.println(lastReconnectAttempt); //
// Attempt to reconnect
Serial.println("trying to connect to mqtt...");
if (reconnect()) {
lastReconnectAttempt = 0;
Serial.println("connect to mqtt OK.");
}
else
{
Serial.println("connect to mqtt FAIL.");
}
}
} else {
// Client connected
Serial.println("mqtt already connected...");
client.loop();
}
Serial.print("millis:");
Serial.println(millis());
}
Serial output:
13:33:54.496> millis:3288
13:33:54.496> millis:3289
13:33:54.496> millis:3290
13:33:54.496> millis:3291
13:33:54.496> millis:3292
13:33:54.496> millis:3293
13:33:54.496> millis:3294
13:33:54.496> millis:3295
13:33:54.496> millis:329onnect to mqtt...
13:33:54.496> illis:4998
13:33:54.496> millis:4999
13:33:54.496> millis:5000
13:33:54.496> now-lastReconnectAttempt: 5001
13:33:54.496> lastReconnectAttempt: 5001
13:33:54.496> trying to connect to mqtt...
13:34:19.753> connect to mqtt FAIL.
13:34:19.753> millis:37153
13:34:19.753> now-lastReconnectAttempt: 32152
13:34:19.753> lastReconnectAttempt: 37153
13:34:19.864> trying to connect to mqtt...
13:34:51.941> connect to mqtt FAIL.
13:34:51.941> millis:69303
13:34:51.941> now-lastReconnectAttempt: 32150
13:34:51.941> lastReconnectAttempt: 69303
13:34:51.941> trying to connect to mqtt...
13:35:24.065> connect to mqtt FAIL.
13:35:24.065> millis:101452
13:35:24.065> now-lastReconnectAttempt: 32150
13:35:24.065> lastReconnectAttempt: 101453
13:35:24.065> trying to connect to mqtt...
13:35:49.818> connect to mqtt OK.
13:35:49.818> millis:127217
13:35:49.818> mqtt already connected...
13:35:49.818> millis:127218
13:35:49.884> mqtt already connected...
13:35:49.884> millis:127222
13:35:49.884> mqtt already connected...
13:35:49.884> millis:127225
13:35:49.884> mqtt already connected...
13:35:49.884> millis:127228
13:35:49.884> mqtt already connected...
13:35:49.884> millis:127233
13:35:49.884> mqtt already connected...
13:35:49.884> millis:127236
13:35:49.884> mqtt already connected...
13:35:49.884> millis:127239
13:35:49.884> mqtt already connected...
13:35:49.884> millis:127243
I have the same issue here. Maybe changing the timeout value in pubsubclient.h is possible, but had no time yet to check. Anyway, I'm not sure if it is possible to decrease the value down to 1 second.
You have the method connect() running every 5s.
If you enter to the .h file, you will find a parameter called MQTT_SOCKET_TIMEOUT set to 15s by default.
So if everything has its default values, you are actually taking at least 20 -25s to complete a succesfull reconecction to your server.
I recommend you to reduce MQTT_SOCKET_TIMEOUT and eliminate the 5s delay, since i don't see it necessary.
How to get rid of delays?
I don't want than connect function freezing my microcontroller (esp12e)
Same as the others. If I lose connectivity to the broker and fail to re-establish it the line:
if (!client.connected()) { ...}
delays the loop of my controller, which is a very bad thing for my animated LED application.
Decreasing MQTT_SOCKET_TIMEOUT from 15 seconds to 1 second has not helped.
Finally found:
. . . which I've been using, but is still not all that great.
Edit: As of Oct 2019, I have stopped using PubSubClient due to its blocking nature as well as lack of QoS along with the fact that it appears to be no longer under development. Rather, I am now using the https://github.com/marvinroger/async-mqtt-client and it appears to work like a charm. No blocking whether or not wifi or the broker are connected/disconnected/reconnecting, etc. Oh, and yes, it supports QoS.
Most helpful comment
Same as the others. If I lose connectivity to the broker and fail to re-establish it the line:
if (!client.connected()) { ...}
delays the loop of my controller, which is a very bad thing for my animated LED application.
Decreasing MQTT_SOCKET_TIMEOUT from 15 seconds to 1 second has not helped.
Finally found:
https://github.com/knolleary/pubsubclient/blob/master/examples/mqtt_reconnect_nonblocking/mqtt_reconnect_nonblocking.ino
. . . which I've been using, but is still not all that great.
Edit: As of Oct 2019, I have stopped using PubSubClient due to its blocking nature as well as lack of QoS along with the fact that it appears to be no longer under development. Rather, I am now using the https://github.com/marvinroger/async-mqtt-client and it appears to work like a charm. No blocking whether or not wifi or the broker are connected/disconnected/reconnecting, etc. Oh, and yes, it supports QoS.