knolleary / pubsubclient

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

mqtt reconnect every 60 seconds #739

Open hathemi opened 4 years ago

hathemi commented 4 years ago
Attempting MQTT connection...connected
pox :1
,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0Attempting MQTT connection...failed, rc=-2 try again in 5 seconds
Attempting MQTT connection...connected
pox :1
,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0Attempting MQTT connection...failed, rc=-2 try again in 5 seconds
Attempting MQTT connection...connected
pox :1
,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0Attempting MQTT connection...failed, rc=-2 try again in 5 seconds
Attempting MQTT connection...connected
...

I'm having trouble with the MQTT client on esp8266. It can't keep a connection alive. every 60seconds it does establish connection. any help!

thijsdebont commented 4 years ago

Source code please :)

hathemi commented 4 years ago
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include <LiquidCrystal_I2C.h>

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <PubSubClient.h>

const char* ssid     = "*******";

const char* password = "*******";

// Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker
const char* mqtt_server = "192.168.x.x";

// Initializes the espClient. You should change the espClient name if you have multiple ESPs running in your home automation system
WiFiClient espClient;
PubSubClient client(espClient);

ESP8266WebServer server(80);   //instantiate server at port 80 (http port)
LiquidCrystal_I2C lcd(0x27,16,2);

#define REPORTING_PERIOD_MS     1000

PulseOximeter pox;
uint32_t tsLastReport = 0; 
String page = "";
String text = "";
String mqttbpm = "";
String mqttspo2 = "";
double data;
double data2;
double data3;
void onBeatDetected()
{
    Serial.println("Beat!");
}

// This functions is executed when some device publishes a message to a topic that your ESP8266 is subscribed to
// Change the function below to add logic to your program, so when a device publishes a message to a topic that 
// your ESP8266 is subscribed you can actually do something
void callback(String topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;

  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // Feel free to add more if statements to control more GPIOs with MQTT

  // If a message is received on the topic room/lamp, you check if the message is either on or off. Turns the lamp GPIO according to the message
  if(topic=="esp8266/output"){
      Serial.print("Changing Room lamp to ");
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");  
      // Subscribe or resubscribe to a topic
      // You can subscribe to more topics (to control more outputs)
      client.subscribe("esp8266/output");  

    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup(void){

Serial.begin(115200);
lcd.init();                      // initialize the lcd 
// Print a message to the LCD.
lcd.begin(16, 2);
lcd.backlight();
lcd.print("Initializing...");
delay(3000);
lcd.clear();

 WiFi.begin(ssid, password); //begin WiFi connection
 Serial.println("");

 // Wait for connection
 while (WiFi.status() != WL_CONNECTED) {
 delay(500);
 Serial.print(".");
}

 Serial.println("");
 Serial.print("Connected to ");
 Serial.println(ssid);
 Serial.print("IP address: ");
 Serial.println(WiFi.localIP());

 server.begin();
 Serial.println("Web server started!");
 if (!pox.begin()) {
        Serial.println("FAILED");
        for(;;);
    } else {
        Serial.println("SUCCESS");
    }
     pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);

    // Register a callback for the beat detection
    pox.setOnBeatDetectedCallback(onBeatDetected);

  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop(void){
   if (!client.connected()) {
    reconnect();
  }
  client.loop();
 //data = analogRead(A0);
 pox.update();
 server.handleClient();

}

@thijsdebont here's my sketch

cyberman54 commented 4 years ago

Same problem here. Did some experiments with mqttClient.setKeepAlive(), but no success. Socket is closed shortly after inital connect and subscription, regardless of keepalive setting. Tested with hive and mosquitto test servers. ESP32, framework arduino-esp32, source code similar as posted above, it has same structure.

slavino commented 4 years ago

In your loops you also need to check WiFi connection state and reconnect also to WiFi if needed.

You can establish your MQTT connection with last "will" topic to monitor on MQTT server when your client dies. Have fun!

cyberman54 commented 4 years ago

@slavino i'm not using Wifi connection, client has TCP/IP over ethernet, and rock stable connection. So the issue must be caused by something on top of OSI layer 4. For whatever reason the socket, from which Wificlient.cpp is reading, is repeatedly closed.

cyberman54 commented 4 years ago

@slavino checked it with Wifi connection, too. Same effect, TCP socket is closed shortly after subscription of a topic. Is this a bug or a feature?

wimdo commented 3 years ago

I have a similar issue ( on ESP32). The ESP is running a webserver and a MQTT client.

#include <WiFi.h>
WiFiClient  client;
WiFiServer server(80);

#include <PubSubClient.h>
PubSubClient clientEsp(client);

When I call server.available(); the MQTT connection is lost.