hirotakaster / MQTT

MQTT for Photon, Spark Core
Other
217 stars 118 forks source link

Async pushing of QOS0 and QOS2 #76

Open mkesselaers opened 5 years ago

mkesselaers commented 5 years ago

Hi,

I have 2 separate processes : 1 is pushing messages every second with QOS0 while the other one sometimes pushes an important event using QOS2.

While debugging the issues that QOS2-messages sometimes are not published, I saw that the PUBREC from Mosquitto was not responded with a PUBREL. As soon as I restarted the device and it reconnects, Mosquitto resended the PUBREC and the device responded immediately.

Is there any reason you can think of where a PUBREC is not responded with a PUBREL?

Thanks in advance, Best regards, Maarten

mkesselaers commented 5 years ago

OK, got further in it. The thing is that I'm using a blocking loop to check that the QOS2-message was successfully published . If I put MQTT::loop() into the blocking loop, it works, but that's not really an elegant solution, off course. How would others tackle such a scenario

` this->lastPhase = phase;

           lastPhaseSent = false;
           lastPhaseAck = false;

            while(!lastPhaseAck){
                    console.log("!!!!!!! TRYING TO SEND !!!!!!!");
                    while(!MQTT::isConnected()){
                            console.log("still not connected...");
                            delay(2000);
                    }

                   lastPhaseSent = MQTT::publish(this->phaseTopic, String::format("{\"phase\":\"%s\"}", phase.c_str()), MQTT::QOS2, &messageid);
                    console.log((String)lastPhaseSent);

                    if(lastPhaseSent){
                            // scenario E,G,H  (success == true, wait 20 seconds while checking ACK every 100ms or try again)
                            console.log("SC E,G,H");
                            loop(); //TODO Really dirty fix. While should be unblocked
                            for(int i=0; i<200 && !lastPhaseAck; i++){
                                    console.log((String)i);
                                    delay(100);

                            }
                    }else{
                            // scenario A, C, D (success == false, wait 3 seconds, check ACK and try again)
                            console.log("SC A,C,D");
                            delay(3000);
                    }

            }`

My QOS-callback code sets lastPhaseAck which is a global in the real code

hirotakaster commented 5 years ago

hi @mkesselaers you need MQTT::loop(). Callback function is called from MQTT::loop().