Closed wiktor-grochal closed 4 years ago
I was able to fix it by placing the following before I set up my mqttClient.
if(wifiClient.connect(mqtt_server, 80)){
Serial.println("Wifi client connected");
}
mqttClient.setServer(mqtt_server, 1883); mqttClient.setCallback(callback);
I was able to solve the issue on an ESP8266 connecting to MQTT broker running on my Raspberry PI by adding the following to the reconnection loop after failure
if(wifiClient.connect(MQTT_SERVER, 1883)) { Serial.println("Wifi client connected to 1883"); } It appears that doing a simple wifi connect clears the issue. Similar logic that alcialex offered above.
Have running 6 tasmota flashed Sonoff Clone identical devices and all where running fine. Until one day, one of them started suddenly to have the issue described here: Connecting to mqtt server returns -2 and does not respond to mqtt command anymore. All of these devices are using the same wifi router and the same wifi password. However, web interface and REST interface ( of the mqtt damaged device ) are working fine. I'm running the following setup: Mqtt Server in docker container (image) eclipse-mosquitto on a ubuntu server. Im using a mqtt password protection, so the suggestions to use the "not secure" wificlient is no option for me. What I have tried to far without success was: -Using a plain mosquitto server outside a docker container -Using another mosquitto user -Using the Serial.println after connection. -Reseting image and configuration and reflashing the whole device. When investigating the mosquitto server log, however I do see the connection tries of the device. It is really a very strange problem. If anyone has more hint for a solution, feel free to write it down here.
The following seems to have resolved my issue. I am running the client on an esp8266 and the broker on a Raspberry Pi. I found the reconnect logic on another thread offered by knolleary. Essentially removing all blocking delay() s from the sketch. I added logic to try up to 15 times. So far (after two days) it has never gone above one attempt. Interesting that it when entering the function, it is almost always disconnected and tries one time . I am monitoring a moisture sensor for an auto watering solution so connection attempts are not often.
void reconnect() { attempts = 0; while (!client.connected() && attempts < 15) { if (millis() - lastReconnectAttempt > 5000) { lastReconnectAttempt = millis(); ++attempts; client.connect("GardenClient"); Serial.println(attempts); if (client.connected()) { // Once connected, publish an announcement... client.publish("/test/","hello world garden here"); } } } }
Update to the code in my post above. The MQTT reconnect issue is resolved. However, while looking over the serial output, I noticed that from time to time, I would get a WDT software reset. I added a yield() statement right after "while (!client.connected() && attempts < 15) {" and the watch dog timer is now happy. I'm also happy.
I'm also getting occasional WDT resets, could you please share your amended code (Inc 'yeild'). Thanks
Here it is Paul. Note: msg is a variable that contains the payload from my sketch. I have the subscribe commented out. This sketch does not subscribe only publishes.
void reconnect() { attempts = 0; while (!client.connected() && attempts < 15) { yield(); if (millis() - lastReconnectAttempt > 5000) { lastReconnectAttempt = millis(); ++attempts; client.connect("GardenClient"); Serial.println(attempts); if (client.connected()) { // Once connected, publish client.publish("/test/Status/Drip",msg); // ... and resubscribe //client.subscribe("inTopic");
}
} }
}
My ESP8266 is showing : Attempting MQTT connection...failed, rc=-2 try again in 5 seconds and the Mosca Server is printing this error : {"pid":27492,"hostname":"JALLILU-PC","name":"IoTChain MQTT Server","level":30,"time":1529353170654,"msg":"authentication denied","client":"IoTChain MQTT Client","v":1}
The problem is the authentification !!! Please How to add user and password to the Mqtt connection !?
@abdoutech93 not sure your question is related to this issue... but as you ask, the docs show you there's a connect
function that takes username and password as arguments - https://pubsubclient.knolleary.net/api.html#connect3
I had this issue too and it was driving me insane...
Thankfully I have just fixed it - basically, in your loop() one simple analogRead(A0) is enough to create the above issue.
I replaced:
dimv = analogRead(DIMMER1_PIN);
with:
if(now % 50 == 0) { dimv = analogRead(DIMMER1_PIN); }
(now is millis() further up)
... and it works perfectly!
So if you are using anything ESP8266 related then be very careful with the analogRead stuff, it's expensive, only do it every X amount of loops.
[Note: I was only able to spot this as I had another sketch that used a button (digital read) rather than a potentiometer and it worked flawlessly].
still have the same problem....Attempting MQTT connection...failed, rc=-2 try again in 5 second. i tried above all advices ...but no output
const char ssid = "vivo V1"; const char password = "qwer1234"; const char* mqtt_server = "192.168.137.72";
WiFiClient espClient; PubSubClient client(espClient); long lastMsg = 0; char msg[50]; int value = 0;
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char topic, byte payload, unsigned int length) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); }
void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect if (client.connect("ESP8266Client")) { Serial.println("connected"); // Once connected, publish an announcement... client.publish("outTopic", "hello world"); // ... and resubscribe client.subscribe("inTopic"); } 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() { Serial.begin(115200); setup_wifi(); client.setServer(mqtt_server, 1883); client.setCallback(callback); }
void loop() {
if (!client.connected()) {
yield();
reconnect();
}
client.loop();
long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
++value;
snprintf (msg, 75, "hello world #%ld", value);
Serial.print("Publish message: ");
Serial.println(msg);
client.publish("outTopic", msg);
}
}
I have not got a definitive answer but I have managed to get my system up and running.
I am running an ESP01 and I had a working system. It worked for weeks. Then it just stopped. I have never found out why.
I then ran the PubSubClient example included in the Arduino IDE. Its pretty much basic. Just a connection via WiFi and then a connection to the MQTT server running on my Raspberry Pi
It failed with connection error everyone is mentioning above.
I tried everything above with no luck. I then installed Mosquito on my PC and tried the same example code against my PC and it worked perfectly.
I upgraded Mosquito on my Pi to version 1.5 and it still wouldn't work.....
At this point I am completely stumped.... I spent days trying every possible solution i could find on the internet.
I then removed the Wifi dongle from my Pi and connected it to my router directly with a cable and rebooted.
The ip address changed...
I changed the ip address in the example sketch, uploaded it, and it now works perfectly!!!
Gulp!
So, the only things that changed is changing from WiFi to a hard wired Ethernet connection and the change of ip address.
HTH
Try another broker like: HiveMQ https://www.hivemq.com/try-out/
All who are trying to connect to the mosquitto broker on Pi...try removing the username & password from the broker and try this: while (!client.connected()) { String clientId = "ESP8266Client-"; clientId += String(random(0xffff), HEX); Serial.print("Attempting MQTT connection..."); // Attempt to connect if (client.connect(clientId.c_str())) { Serial.println("connected"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 3 seconds"); // Wait 3 seconds before retrying delay(3000); }
I'm having the same "Attempting MQTT connection...failed, rc=-2" I'm using a docker version of eclipse-mosquitto for my broker its version 1.5.4. I my Docker runs on Centos7 on a Lenovo W510 and it uses a wired Ethernet connection to my home network. I had a TI 1294 with the PubSubClient working using a wired Ethernet connection. For a number of reasons I decide to switch to using an ESP8266WiFi device. I started by getting the RFID reader to read RFID tags and to output a JSON string, which worked, in fact the output looks like this: {"epochTime":"1543034961","sensor":"rfidRdr01","rfid":"0000000735"} In searching various web sites for assistance I came across quite a few, many suggesting network issues, but my epochTime comes from an NTP server I set up on a different Linux machine in my network, so I figure I'm ok on the network. Here's my code (I've removed the RFID tag processing code to reduce the size, the code still runs)
//#define use7491E_Reader
// Variables WiFiClient rfidRdr01; // change name when multiple readers are in the network WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, "192.168.0.7", 3600, 60000); SoftwareSerial RFID(13, 15); // RX and TX PubSubClient client(rfidRdr01); const char ssid = "xxxxxxxxxx"; // Credentials to connects to WiFi router const char password = "xxxxxxxxxx"; const char* mqtt_server = "192, 168, 0, 200"; // MQTT broker IP address int mqttPort = 1883; char mqttMsg[800]; //buffer used to publish messages via mqtt unsigned long epochTime = 0; char pubtopic[] = "sensors/rfid"; String clientId = "rfidRdr01";
void callback(char topic, byte payload, unsigned int length) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (unsigned int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); }
// This function connects the ESP8266 to the LAN void setup_wifi() { delay(10); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.print("WiFi connected - ESP IP address: "); Serial.println(WiFi.localIP()); }
// This function reconnects the ESP8266 to the MQTT broker void reconnect() { while (!client.connected()) { Serial.print("Attempting MQTT connection..."); if (client.connect(clientId.c_str())) { } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(); // Wait 5 seconds before retrying delay(5000); } } }
String getTagId() { return "0000000000"; }
String getTagId() { return "0000000000"; }
// This function builds the Json message String buildJson(String id, String sensor, String et) { String mqttMsg = "{\"epochTime\":\""; mqttMsg = mqttMsg + et; mqttMsg = mqttMsg + "\",\"sensor\":\""; mqttMsg = mqttMsg + sensor; mqttMsg = mqttMsg + "\",\"rfid\":\""; mqttMsg = mqttMsg + id; mqttMsg = mqttMsg + "\"}"; return mqttMsg; }
void setup() { Serial.begin(115200); RFID.begin(9600); // start serial to RFID reader setup_wifi(); timeClient.begin(); client.setServer(mqtt_server, 1883); client.setCallback(callback); }
void loop() { String rfTagId = getTagId(); timeClient.update(); epochTime = timeClient.getEpochTime(); String rfidJsonPayload = buildJson(rfTagId, "rfidRdr01", String(epochTime)); Serial.println(rfidJsonPayload ); char buf[67]; rfidJsonPayload.toCharArray(buf, 67); // connect to mqtt broker if (!client.connected()) { reconnect(); } if (client.connected()) { client.publish(pubtopic, buf); } }
As you can see my code looks like most of the others here and the MQTT code was mimicked from the PubSubClient library provided by Arduino Here's the end of the compile prior to move the code to the ESP8266: Using library ESP8266WiFi at version 1.0 in folder: /home/dbristow/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi Using library PubSubClient at version 2.7 in folder: /home/dbristow/Arduino/libraries/PubSubClient Using library NTPClient-master at version 3.1.0 in folder: /home/dbristow/Arduino/libraries/NTPClient-master Using library SoftwareSerial at version 1.0 in folder: /home/dbristow/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/SoftwareSerial
Going by my own experience I think your issue is this. In your loop() each time you are dealing with creating a json payload, printing it and publishing it. You seem to do this every time.
The issue is that the PubSubClient object needs to be running its update function repeatedly and without significant delays between multiple calls. By having a large chunk of other code that runs each time between the update function it messes with the ability for it to connect properly to the server.
Right now I can't actually see your update call, but I have a strong hunch that that is the issue. Look at my solution further up the thread, I had your issue and the solution fixed it.
Thanks for the suggestion, but I'm not using an analog read I'm using a SoftwareSerial connection to the RFID reader. Furthermore, each time a tag rolls over the reader I need to get its value and due to the speed at which the reader works I don't try to read a tag any faster than one per second. So I recall somewhere there was a warning about the SoftwareSerial code interfering with the TCP of the ESP WiFi code. So I ran the "getTagId" function with no SoftwareSerial use by simply waiting for 30 seconds an the return a constant of a known RFID tag ie "0000000735". But alas I still get the dreaded rc=-2 response. To eliminate the possibility my MQTT broker is not working properly I have a Java application which simulates the RFID reader and creates an MQTT message in the same format as the sketch I shared earlier. I ran this application on the NTP server and another linux laptop and in both cases I can see the message gets processed by the Eclipse-Mosquito Docker container.
Well it certainly helps if you read what others have written! I feel a little foolish... the problem identified above by chenirl is what mine was. I ended up reviewing the source code to the PubSubClient and saw that the connect uses a couple of different set of parameters. Once I declared IPAddress mqtt_server(192, 168, 0, 200); instead of a char* my sketch worked. :)
The connection to my MQTT broker on a raspberry worked for months... probably after an upgrade it started to fail, but not always... just most of the time. The solution for me was to move to broker from wireless to wired. Now using the wired-ip it works, on the wireless-ip most of time not!
The connection to my MQTT broker on a raspberry worked for months... probably after an upgrade it started to fail, but not always... just most of the time. The solution for me was to move to broker from wireless to wired. Now using the wired-ip it works, on the wireless-ip most of time not!
Exactly what happened to me...
What does mean -1 in mqttClient.state?
I have problem with connection and state rc = - 1... What is this?
What does mean -1 in mqttClient.state?
I have problem with connection and state rc = - 1... What is this?
https://github.com/knolleary/pubsubclient/blob/master/src/PubSubClient.h line 48.
Could you help me? I have problem with connect to my Losant device I have mqttClient.state -1 I don't know how can I repair it...
My issue:
https://github.com/esp8266/Arduino/issues/5508
But closed.. I would like to help with it. :(
I built a device based on homie on esp8266 which used to connect to mosquitto on raspberry 2 for months without any issues.
Now i upgraded to raspberry 3 and got the same issues as described above (Attempting to connect endlessly, mosquitto log showed "Socket error on client
After some investigation i found out that the rpi3 was connected both, wired and wireless, having two different IP adresses. A nslookup showed this (homer is the name of the rpi3):
C:\Users\foo>nslookup homer
Server: fritz.box
Address: 192.168.1.250
Name: homer
Addresses: 192.168.1.96 <- the Wifi adress
192.168.1.97 <- the wired adress
After deactivating the Wifi and removing (force recreation) of all DNS entried in my router the problem disappeared. Even the device which was in the Attempt to connect - loop suddenly got a connection. The nslookup command proved that the rpi3 now was available only by one IP adress:
C:\Users\foo>nslookup homer
Server: fritz.box
Address: 192.168.1.250
Name: homer
Address: 192.168.1.97
Just for completeness here my solution - my errorcode was rc=-1 (tried to connect via tasmota esp8226 firmware).
Reason: I used a too long username/password in my mosquitto server. Solution: Reduced my username/password to 12 chars and it worked!
Try This:
Use: IPAddress mqttServer(xxx.xxx.xxx.xxx); Instead of: const PROGMEM char* mqttServer = "xxx.xxx.xxx.xx"; For your setServer: mqttClient.setServer(mqttServer, mqttPort);
Thanks, This solution fixed my reboot issue. basically eliminating the PROGMEM.
Use: IPAddress mqttServer(xxx.xxx.xxx.xxx); Instead of: const PROGMEM char* mqttServer = "xxx.xxx.xxx.xx"; For your setServer: mqttClient.setServer(mqttServer, mqttPort);
i also tried all hack but now able to get communication with broker on cloud with above suggestion on this form. Thank you so much all.
Hi Averri, I add WiFi.mode(WIFI_STA); above WiFi.begin(ssid, password);. It works.
This worked perfectly!
I had the same error. In my case the broker was rabbitmq and rabbitmq does not allow connection with guest user. You might wanna try providing user credentials.
client.connect(client_id.c_str(), mqtt_user.c_str(), mqtt_pass.c_str());
something like this.
The solution to this problem is to enable authentication on the mosquitto broker and use user name and password on the client connect call.
Just updated a device that's been running for years and ran into this same issue :( I'm running rabbitmq with authentication enabled and here's a snippet of the server-side output:
2020-05-31 17:08:19.168 [error] <0.5894.59> MQTT cannot parse frame for connection '10.42.2.0:29335 -> 10.42.1.175:1883', unparseable payload.......,[{file,"src/rabbit_mqtt_frame.erl"},{line,145}]},{rabbit_mqtt_frame,parse_frame,3,[{file,"src/rabbit_mqtt_frame.erl"},{line,59}]},{rabbit_mqtt_reader,parse,2,[{file,"src/rabbit_mqtt_reader.erl"},{line,311}]},{rabbit_mqtt_reader,process_received_bytes,2,[{file,"src/rabbit_mqtt_reader.erl"},{line,260}]},{gen_server2,handle_msg,2,[{file,"src/gen_server2.erl"},{line,1050}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,247}]}]}
I get similar message every time it attempts to reconnect.
What I found to be a problem is , if you leave the connection idle for more than a sec, it gets closed with socket errors, In the original example published for this library, if you remove the continuous message publish in the main loop, you can replicate the same error. In my code I just kept this continuous ping every 2 secs , apart from my other message publish/subscribe needs. Havent faced this issue after that. The "AP mode" fix is not a solution.
I never get a connection. It fails to even make the connection successfully. All I did was update the board definitions in the IDE. Flashed and it failed so then I updated this lib..flashed again and failure. Failure all around now :)
Are you using any sort of MDNS discovery or similar before attempting the MQTT broker connection ?For me this was also an issue, ESP8266 MDNS library seems to do something to the Wifi stack after running a mdns query. It would actually not even appear on the router's device list although connection status on wifi library would still return 3. The solution for me was to save the IP and port after discovery to eeprom and then do a restart and attempt connection with mqtt broker. To verify this, check the device list on your router. I am sure your board wont be in the connected device list, thats the reason its failing with rc - 2
I don't think that's the case or a I wouldn't be seeing the attempts on the rabbitmq server to authenticate. I have an IP etc and it is attempting to connect..
Seems to be a new issue , are you using authentication? I was using Mosquitto broker on the raspberry pi. May be whatever I faced is typical to Mosquitto.
On Mon, Jun 1, 2020 at 12:11 PM Travis Glenn Hansen < notifications@github.com> wrote:
I don't think that's the case or a I wouldn't be seeing the attempts on the rabbitmq server to authenticate. I have an IP etc and it is attempting to connect..
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/knolleary/pubsubclient/issues/203#issuecomment-636643217, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACL7KNJXVC5AA6ZSU5W4RS3RUNERZANCNFSM4CQNJPTQ .
I’ve been using authentication with rabbitmq on the device for years.
Hi everyone. I'm using a Raspberry Pi running Mosquitto over websockets on port 9001 with username and password. The username and password are less than 10 characters I don't know why I'm getting error -1 in the client state. However, I can connect to the server with a JavaScript client with the same data. This is my code:
const char ssid = "my_ssid"; const char password = "my_network_password"; const char mqtt_server = "192.168.1.36"; const int mqtt_port = 9001; const char mqtt_username = "user"; const char* mqtt_password = "password";
WiFiClient espClient; PubSubClient client(espClient); long lastMsg = 0; char msg[50]; int value = 0;
void setup() { Serial.begin(115200); setup_wifi(); client.setServer(mqtt_server, mqtt_port); client.setCallback(callback); }
void setup_wifi() { delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); }
void callback(char topic, byte payload, unsigned int length) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); // Rest of code }
void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect if (client.connect("ESP32Client", mqtt_username, mqtt_password)) { Serial.println("connected"); // Rest of code } else { Serial.print("failed, rc="); Serial.print(client.state()); // I'm getting -1 Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } }
void loop() { if (!client.connected()) { reconnect(); } client.loop(); // Rest of code }
The output is: Attempting MQTT connection...failed, rc=-1 try again in 5 seconds. I will appreciate your help, thanks.
I don't see any websocket implementation in your sketch. And AFAIK this is not supported out of the box by Pubsubclient. Try the regular MQTT connection (1883) if your broker supports this.
This issue is 4 years old and too generic to be worth keeping open. Lots of people have issues connecting and every single one is a different underlying reason.
[ tested and workinf for my case ] check if your case it help i made a routing in code like below im not testin gmqttclient connection, but the underlying espclient i checking with connection with 80 port, i hosted a apache just for pining purpose nothing elsem , in main loop i check it for connection purpose and in global variable i setting the indication of internet avalabel if ping is success as belo, and in connect loop of mq tt i check if internet is availeble then only i reconect to it, elese i dont, and one more obseration , using IP it workes satisfacotry but if i use domain instead of ip , it wont work as intended, Im stuck to manage broker ip , because shoing ip directoly is not a good solution
ping function
boolean pingServer()
{
// if (pinger.connect("broker.pongohome.in", 80))
if (pinger.connect(brokerIP, 80))
{
// Serial.println("ping : true");
internetAvailable = true;
// Make a HTTP request:
}
else
{
// Serial.println("ping : false");
internetAvailable = false;
}
return internetAvailable;
}
in reconnec logic of mqtt do this
void reconnect()
{
// Loop until we're reconnected
if (internetAvailable)
{
while (!client.connected())
{
// Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "XXXXX-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str()))
{
// Serial.println("connectedMQTT");
client.subscribe(topicX.c_str());
//publish to some topi to know status of connectivity
}
else
{
// Serial.print("failed, rc=");
// Serial.print(client.state());
// Wait 5 seconds before retrying
}
}
}
else
{
// Serial.println("Internet not present so not pinging 1883"); // it continuesly print it, better keep commended this line
}
}
let know if it work in your case also, pub sub lib, generic async mqtt lib has same underlying issue , that breakage of internet from ISP causes continuous disconnection status, keep ing pending reconnect state, but in this patch try if working in your case
Hi, i cant connect to broker on my raspberry. Broker: Mosquitto 1.4.10
on serial i m getting rc=-2 acording to documentation it is network connection failed. On mosquitto log i m getting
New connection from 192.168.1.111 on port 1883
for the first few minutes and then these errors occur:As you can see networking seems fine and there is some other issue with communication between arduino and rpi. Remote client on my laptop connects to the broker without any problems.
Hardware i m using is: arduino nano with ethernet shield (the one with the sd card slot)
my sketch: basicly copied example with delay between connections rised to 20s:
if u need more information i will be happy to share