Particle electron issue to connect to MQTT broker

I am testing the following example (copied from similar thread in Particle community), first of all, it works if the MQTT broker is set to “broker.emqx.io” (a free public MQTT broker online), but it is not working with my own MQTT broker with IP address (192.168.0.186), everything else is the same. I have tested my MQTT broker with Paritcle Photon and verified working.

So, the question is why Particle Electron can’t connect to my local/working MQTT broker (192.168.0.186) but it can connect to online MQTT broker (broker.emqx.io)? any suggestions?

Thanks,

#include "MQTT.h"
void callback(char* topic, byte* payload, unsigned int length);

/**
 * if want to use IP address,
 * byte server[] = { XXX,XXX,XXX,XXX };
 * MQTT client(server, 1883, callback);
 * want to use domain name,
 * exp) iot.eclipse.org is Eclipse Open MQTT Broker: https://iot.eclipse.org/getting-started
 * MQTT client("iot.eclipse.org", 1883, callback);
 **/

byte server[] = { 192,168,0,186 };//the IP of broker
MQTT client("broker.emqx.io", 1883, callback);
//MQTT client(server, 1883, callback);

uint16_t qos2messageid = 0;

// receive message
void callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;

    if (!strcmp(p, "RED"))
        RGB.color(255, 0, 0);
    else if (!strcmp(p, "GREEN"))
        RGB.color(0, 255, 0);
    else if (!strcmp(p, "BLUE"))
        RGB.color(0, 0, 255);
    else
        RGB.color(255, 255, 255);
    delay(1000);
}

// QOS ack callback.
// if application use QOS1 or QOS2, MQTT server sendback ack message id.
void qoscallback(unsigned int messageid) {
    Serial.print("Ack Message Id:");
    Serial.println(messageid);
}

void setup() {
    Serial.begin(9600);
    RGB.control(true);

    // connect to the server
     client.connect("MyMQTT");

    // add qos callback. If don't add qoscallback, ACK message from MQTT server is ignored.
     client.addQosCallback(qoscallback);
    // publish/subscribe
    if (client.isConnected()) {
        // get the messageid from parameter at 4.
        uint16_t messageid;
        client.publish("test/message", "hello world QOS1", MQTT::QOS1, &messageid);
        Serial.println(messageid);

       Serial.println(" connected");
        // if 4th parameter don't set or NULL, application can not check the message id to the ACK message from MQTT server.
        client.publish("outTopic/message", "hello world QOS1(message is NULL)", MQTT::QOS1);

        // QOS=2
        client.publish("outTopic/message", "hello world QOS2", MQTT::QOS2, &messageid);
        Serial.println(messageid);

        // save QoS2 message id as global parameter.
        qos2messageid = messageid;

        // MQTT subscribe endpoint could have the QoS
        client.subscribe("inTopic/message", MQTT::QOS2);
    }
}

void loop() {
    
        // publish/subscribe
    if (client.isConnected()) {
        // get the messageid from parameter at 4.
        uint16_t messageid;
        client.publish("outTopic/message", "hello world QOS1", MQTT::QOS1, &messageid);
        Serial.println(messageid);

        delay(1000);
        // if 4th parameter don't set or NULL, application can not check the message id to the ACK message from MQTT server.
        client.publish("outTopic/message", "hello world QOS1(message is NULL)", MQTT::QOS1);

        // QOS=2
        client.publish("outTopic/message", "hello world QOS2", MQTT::QOS2, &messageid);
        Serial.println(messageid);
        delay(1000);

        // save QoS2 message id as global parameter.
        qos2messageid = messageid;

        // MQTT subscribe endpoint could have the QoS
        client.subscribe("inTopic/message", MQTT::QOS2);
    }
    else
    {
        client.connect("MyMQTT");
        Serial.println("not connected");
        delay(1000);
    }
    
    if (client.isConnected())
        client.loop();
}

Your IP address (192.168.x.x) is only known locally but the Electron needs to find the server from outside your local network.

You may need to setup port forwarding and use your WAN address instead.

This works for the Photon since it is connected to that same subnet and hence can access that local IP, but cellular devices are not connected to your local network and hence need a globally known address in order to establish a connection.

1 Like

Thank you ScruffR, good catch! this must be the case.