mlesniew / PicoMQTT

ESP MQTT client and broker library
GNU Lesser General Public License v3.0
219 stars 25 forks source link

Client and Server/Broker mode running concurrently AND server/broker mode callbacks #23

Closed BoltSwith closed 8 months ago

BoltSwith commented 8 months ago

Greetings,

  1. Please, can I declare and running the two modes - client and server/broker modes - concurrently? What I mean is can I declare and use both the client object and the server object and define separate callbacks for them? e.g. SEE CODE SNIPPET BELOW:

//######################################################################################

// Code for illustration

include

include

PicoMQTT::Client mqtt_Client("broker.hivemq.com"); PicoMQTT::Server mqtt_Server;

void setup() { // Usual setup Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin("MyWiFi", "password");

// Subscribe the CLIENT to a topic pattern and attach a callback
mqtt_Client.subscribe("#", [](const char * topic, const char * payload) {
    Serial.printf("Received message in topic '%s': %s\n", topic, payload);
});

// Subscribe the SERVER to a topic pattern and attach a callback
mqtt_Server.subscribe("#", [](const char * topic, const char * payload) {
    Serial.printf("Received message in topic '%s': %s\n", topic, payload);
});

// Start the clienth and the broker
mqtt_Client.begin();
mqtt_Server.begin();

}

void loop_Client() { // This will automatically reconnect the client if needed. Re-subscribing to topics is never required. mqtt_Client.loop(); }

void loop_Server() { // This will automatically reconnect the client if needed. Re-subscribing to topics is never required. mqtt_Server.loop(); }

//######################################################################################

I know it's mentioned in the first item on the FEATURES of the library that "Client and broker mode supported" . I will like to know if this mean both modes can run concurrently or separately.

  1. I intend implementing the Server/Broker Mode. However, combing through the library and examples, I couldn't find/implement a means of detecting when a Client have connected, disconnected, subscribed or unsubscribed.

I could find the private functions on_connected, on_disconnected, on_subscribe and on_unsubscribe of the Server Class, however, I couldn't find a way to apply this functions.

Kindly assist. Many thanks.

mlesniew commented 8 months ago

You can have any number of clients and servers in your code simultanously. Having one server and one client will work too. You just need to call the loop() method of each server and client instance in your loop() function.

You can run some code when a client connects or disconnects to your broker by overriding the methods you mentioned in a subclass. Note that they are declared as virtual protected, not private. Something like this should work:

class MyBroker: public PicoMQTT::Server {
    protected:
        virtual void on_connected(const char * client_id) override {
            Serial.printf("Client %s connected.\n", client_id);
        }
};
BoltSwith commented 8 months ago

Many thanks for the swift response. I created and ran one client object and one server object, and it worked as you mentioned.

As for the Server "callbacks", I tried overriding the methods as you advised, but still, after running the code, I still don't get notified of Client connections or disconnection. The client connects success to the ESP32 broker (on my local network), and I'm able to exchange messages between the client and broker, however, no notifications (on_connected, on_disconnected etc don't execute) when the client connects or disconnects. I'm using "MQTT-Explorer-0.4.0-beta1" which is running on my PC as the client.

Below is the Subclass of Server that I created.

//###################################################

class mqtt_ServerExtended : public PicoMQTT::Server { protected: virtual void on_connected(const char client_id) override { // Implementation of the function Serial.printf("Client %s connected.\n", client_id); } virtual void on_disconnected(const char client_id) override { // Implementation of the function Serial.printf("Client %s disconnected.\n", client_id); } virtual void on_subscribe(const char client_id, const char topic) override { // Implementation of the function Serial.printf("Client %s subscribed.\n", client_id); } virtual void on_unsubscribe(const char client_id, const char topic) override { // Implementation of the function Serial.printf("Client %s unsubscribed.\n", client_id); } };

//###################################################

What could be missing?

BoltSwith commented 8 months ago

Greetings.

So, I've been able to fix this issue base on the guide provided. It initially didn't work because, after overriding the on_connected(), on_disconnected() etc. methods in the subclass created, I still declared the Server object using "PicoMQTT::Server" instead of the new subclass "MyBroker". The code works fine now, with "on_connected()" and "on_disconnected()" being called whenever an external client connects and disconnects to the ESP32.

Thanks for the support.