Imroy / pubsubclient

A client library for the ESP8266 that provides support for MQTT
MIT License
433 stars 115 forks source link

How to set the callback from a c++ class? #81

Closed suculent closed 6 years ago

suculent commented 7 years ago

First of all, sorry that I'm asking here... it seems to me like a generic C/C++ question but it's probably too generic to be searched on Google. I was grown somewhere between Z80 assembler and high-level languages like Objective-C, Swift and JavaScript, so the C-side is temporarily unfamiliar to me.

In your header, you declare:

//! Set the callback function
PubSubClient& set_callback(callback_t cb) { _callback = cb; return *this; }

In my .h:

class MyClass {
 public: 
    PubSubClient *mqtt_client;
    // I had to inline the callback here because otherwise linker has issues with undefined attribute types
     inline void mqtt_callback(const MQTT::Publish& pub) {
      Serial.println("*TH: MQTT callback...");
      if (pub.has_stream()) {
        Serial.print(pub.topic());
        Serial.print(" => ");
        if (pub.has_stream()) {
          uint8_t buf[MQTT_BUFFER_SIZE];
          int read;
          while (read = pub.payload_stream()->read(buf, MQTT_BUFFER_SIZE)) {
            // Do something with data in buffer
            Serial.write(buf, read);
          }
          pub.payload_stream()->stop();
          Serial.println("stop.");
        } else {
          Serial.println(pub.payload_string());
        }
      }
    }
}

In my .cpp:

mqtt_client = new PubSubClient(*wifi_client, mqtt_url.c_str());
if (mqtt_client->connect(MQTT::Connect(id)
                .set_clean_session()
                .set_will(willTopic, disconnected_response.c_str())
                .set_auth(user, pass)
                .set_keepalive(30)
              )) {
    // The callback function does not get called. Why?
    mqtt_client->set_callback([this](const MQTT::Publish &pub) {
      Serial.print("*MQTT Callback called...");
      this->mqtt_callback(pub);
    });
}

The callback function does not get called. Why?

suculent commented 6 years ago

After couple weeks I've noticed that the PubSubClient::loop() function is not called in the upper code... which was the reason why the callback didn't happen and no messages were received.

Everything started working normally after adding the forgotten call.