Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing user context in MQTT and QoS callbacks #8

Open
pavel-benes opened this issue Mar 2, 2018 · 2 comments
Open

Missing user context in MQTT and QoS callbacks #8

pavel-benes opened this issue Mar 2, 2018 · 2 comments

Comments

@pavel-benes
Copy link

Hi,

I am using MQTT-TLS library from C++ instance. Unfortunately one function pointer is not enough to reference C++ class member function. I have solved this by introducing one extra argument 'userData' to initialization and callback methods. More details are here:

pavel-benes@3e4d89f
pavel-benes@24f5d82

The usage pattern is to provide MQTT-TLS library with pointer to static function and there use the (cast) userData value to reference the right class instance.

Do you think this would fit into you library? Since this is the only difference in my fork, I would like to abandon it and start to use your version.

Thanks a lot,

Regards,

Pavel

@hirotakaster
Copy link
Owner

Hi @pavel-benes ,

Thank you for your diff.

I think you want to use the user specified define data when MQTT client get a data with. But "userData" is not modified by MQTT class. If you want to use this pointer data, I think it's better don't depend on callback function.
I would like to please show me your sample source code with this userData function.

And thank you for your comment about the getByte().

Thank you

@pavel-benes
Copy link
Author

pavel-benes commented Mar 5, 2018

Hi,

thank you for the quick response. Sorry about not providing the use case in the first place ... Here is the fragment of usage:

// class header
class AzureIotHub {
 ...
    MQTT *mqttClient;
...
    bool connect(const char *hostName, const char *deviceId, const char *sasToken);
    static void messageCallback(char *topic, uint8_t *payload, unsigned int length,void* userData=NULL);
    static void qosCallback(unsigned int msgId, void* userData=NULL);    
}

// class implementation
bool AzureIotHub::connect(const char *hostName, const char *deviceId, const char *sasToken) {
    ...
    //HINT Pass 'this' as 'userData' parameter to MQTT class
    mqttClient = new MQTT((char *) hostName, 8883, &AzureIotHub::messageCallback, 512, this);
    ...
    mqttClient->addQosCallback(&AzureIotHub::qosCallback);
    ...
}

//HINT Use the previously set 'userData' as pointer to AzureIotHub class instance
void AzureIotHub::messageCallback(char *topic, uint8_t *payload, unsigned int length, void* userData) {
    if (userData != NULL) {
        ((AzureIotHub*) userData)->handleMessage(topic, payload, length);
    } else {
        ERROR("NULL user data.");
    }
}

void AzureIotHub::qosCallback(unsigned int msgId, void* userData) {
    if (userData != NULL) {
        ((AzureIotHub*) userData)->handleQosConfirmation(msgId);
    } else {
        ERROR("NULL user data.");
    }
}

This indirection with the userData parameter allows me to call C++ member function as callback from MQTT library. It is not a critical feature to have, it can be solved for example by making AzureIotHub a singleton or define some listener class within MQTT library, but this approach with userData is (arguably) a little bit more flexible.

Thanks,

Regards,
Pavel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants