Following code comes form the Adafruit Mqtt documentation:
// Adjust as necessary, in seconds. Default to 5 minutes (300 seconds).
#define MQTT_CONN_KEEPALIVE 300
// ping the server to keep the mqtt connection alive
// NOT required if you are publishing once every KEEPALIVE seconds
if(! mqtt.ping()) {
mqtt.disconnect();
}
What does the "MQTT_CONN_KEEPALIVE" actually do? I cannot figure it out.. If i write the code as shown above here and put it in my loop, then the ping is executed constantly, and all packets are rejected... I was expecting that the MQTT_CONN_KEEPALIVE variable is used in the ping() function to execute the ping only if the 300 seconds have passed, but id does not seem to be like that. How am I supposed to write the code in order to ping only once every few minutes?
MQTT Keep Alive is part of MQTT protocol to maintain a connection between broker and clients. You can read more about it in the documentation.
MQTT uses a TCP/IP connection that is normally left open by the client so that is can send and receive data at any time. To detect a connection failure MQTT uses a ping system where it sends messages to the broker at a pre-determined interval if no messages have been sent after a certain period (KeepAlive).
Specific to Adafruit_MQTT implementation, if you publish data and you are sure that you will publish data within the time period set by MQTT_CONN_KEEPALIVE, then you are good to go.
If the server/broker didn't receive data or PINGREQ from client within the MQTT_CONN_KEEPALIVE + an extra of 50% of MQTT_CONN_KEEPALIVE, the broker will disconnect from the network(timeout) and the client will have to re-establish the connection.
So if a MQTT client only subscribe to a topic without publishing, the client then must send the ping (PINGREQ) to the broker at least once in every MQTT_CONN_KEEPALIVE sec. However, you don't want to constantly ping the server. One way of doing it is only send the mqtt.ping() every MQTT_CONN_KEEPALIVE sec.
#define MQTT_KEEP_ALIVE 300
unsigned long previousTime = 0;
loop() {
if((millis() - previousTime) > MQTT_KEEP_ALIVE * 1000) {
previousTime = millis();
if(! mqtt.ping()) {
mqtt.disconnect();
}
}
// do something else
}