Hello,
I have an esp8266 connected to my wifi network, which uses the PubSubClient library to send messages via MQTT. I have a Node.js server and a Mosquitto broker running with Docker.
Here is my docker-compose:
version: "3"
services:
db:
image: postgres:13.2
environment:
- POSTGRES_DB=XXXXX
- POSTGRES_USER=XXXXX
- POSTGRES_PASSWORD=XXXX
ports:
- "5432:5432"
api:
build: .
volumes:
- ./src:/app/src
ports:
- "3000:3000"
depends_on:
- mosquitto
- db
environment:
- POSTGRES_DB=XXXXXX
- POSTGRES_USER=XXXXX
- POSTGRES_PASSWORD=XXXXXX
- POSTGRES_HOST=db
mosquitto:
image: eclipse-mosquitto:latest
container_name: mosquitto
logging:
options:
max-size: 10m
restart: always
ports:
- "1883:1883"
- "9001:9001"
volumes:
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf
Here is my mosquitto.conf:
allow_anonymous true
listener 1883 0.0.0.0
I also share the code where I test the connection from my esp8266:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// I hide my ssid password and public ip
const char* ssid = "XXXXXX";
const char* password = "XXXXXXX";
IPAddress server(192, 168, X, XX);
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();
}
WiFiClient espClient;
PubSubClient client(espClient);
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("arduinoClient")) {
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);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
client.setServer(server, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}
My Node.js server can connect and send messages using the IP of the Mosquitto container (mqtt://172.19.0.3:1883).
My problem is that my ESP cannot connect to the MQTT broker using the public IP of my computer 192.168.X.XX:1883.
However, this same ESP can connect to my Node.js server running on port 3000 and send websockets via the same IP address: 192.168.X.XX:3000 (I want to replace the SocketIO system with MQTT).
I don't have any authentication in my mosquitto.conf file and I have opened up to all IPs with the line: listener 1883 0.0.0.0.
The error I get in the logs of my esp8266 is:
Serial.print("failed, rc=");
Serial.print(client.state());
failed, rc = 5
I don't have a firewall on my Ubuntu that blocks port 1883, and port 1883 is accessible.
If I run the following command from my computer:
mosquitto_pub -h localhost -p 1883 -t "topic/test" -m "Hello MQTT"
the broker receives the message.
Here are the logs from my Mosquitto broker where we see that my Node.js is connected to the broker :
1711064925: mosquitto version 2.0.18 starting
1711064925: Config loaded from /mosquitto/config/mosquitto.conf.
1711064925: Opening ipv4 listen socket on port 1883.
1711064925: mosquitto version 2.0.18 running
1711064932: New connection from 172.19.0.4:40386 on port 1883.
1711064932: New client connected from 172.19.0.4:40386 as mqttjs_7561f51c (p2, c1, k60).
Here is a screenshot of my Docker:
I can't find a solution, if anyone has any ideas why my ESP can't connect to my broker, it would help me a lot.
Thank you very much.