arcoirislabs / cordova-plugin-mqtt

MqTT Cordova Plugin for Apache Cordova (> v3.0)
MIT License
86 stars 49 forks source link

Attempted to send a second callback for ID #29

Closed airomyas closed 7 years ago

airomyas commented 7 years ago

I'm using the plugin in an ionic project with angularjs I'm trying to use the plugin's subscribe method subscribe to multiple topics like code below. The result is only one of element in array $scope.gateInfo can successfully subscribe to the topic and I found the error message in logcat which says : W/CordovaPlugin: Attempted to send a second callback for ID: CordovaMqTTPlugin592666074 After some searching I found that to eliminate this error request plugin support asynchronous communication between javascript and plugin. Is it true? Any ideas are welcome.

var mqttSetupSubscribe = function(){
    var arr = [];
    for (var i = $scope.gateInfo.length - 1; i >= 0; i--) {
        arr.push(mqttSubscribe(i));
    }
    return $q.all(arr);
}

var mqttSubscribe = function(index){
    var defer = $q.defer();
    var subTopic = mqttSubDevInfo + $scope.gateInfo[index].serial;

        cordova.plugins.CordovaMqTTPlugin.subscribe({
        topic: subTopic,
        qos:0,
        success:function(s){
            cordova.plugins.CordovaMqTTPlugin.listen(subTopic, 
                function (payload, params, topic, topic_pattern) {
              alert(JSON.stringify(payload));
            });
            defer.resolve();
        },
        error:function(e){
            defer.reject();
        }
        });
    return defer.promise;
}

// mqttSetupSubscribe().then(function(){ alert("done"); })

arcoirislabs commented 7 years ago

Hi, In the plugin, the native part of Cordova architecture allows synchronous and asynchronous communication. The asynchronous communication is allowed only when the native part generates callbacks on its own. Such as messageArrived callback. In your case, if the topics are in a pattern, I would suggest you to use wildcard topics (#,+)

Because as far as I understand, the subTopic var is having a pattern, where mqttSubDevInfo var is common string between the topics you are trying to subscribe. Here is a better suggestion

  1. Use Wildcard topics.
  2. Use listen callback once. And use pattern variables as mentioned in ReadMe.
  3. Don't use defer with Cordova plugins where synchronous communication happens between native and JavaScript bridge.

Sent from my iPhone

On 19-Jul-2017, at 8:32 AM, airomyas notifications@github.com wrote:

I'm using the plugin in an ionic project with angularjs I'm trying to use the plugin's subscribe method subscribe to multiple topics like code below. The result is only one of element in array $scope.gateInfo can successfully subscribe to the topic and I found the error message in logcat which says : W/CordovaPlugin: Attempted to send a second callback for ID: CordovaMqTTPlugin592666074 After some searching I found that to eliminate this error request plugin support asynchronous communication between javascript and plugin. Is it true? Any ideas are welcome.

var mqttSetupSubscribe = function(){ var arr = []; for (var i = $scope.gateInfo.length - 1; i >= 0; i--) { arr.push(mqttSubscribe(i)); } return $q.all(arr); }

var mqttSubscribe = function(index){ var defer = $q.defer(); var subTopic = mqttSubDevInfo + $scope.gateInfo[index].serial;

    cordova.plugins.CordovaMqTTPlugin.subscribe({
    topic: subTopic,
    qos:0,
    success:function(s){
        cordova.plugins.CordovaMqTTPlugin.listen(subTopic, 
            function (payload, params, topic, topic_pattern) {
          alert(JSON.stringify(payload));
        });
        defer.resolve();
    },
    error:function(e){
        defer.reject();
    }
    });
return defer.promise;

} // mqttSetupSubscribe().then(function(){ alert("done"); })

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

arcoirislabs commented 7 years ago

@airomyas You can try this code

var subTopic = mqttSubDevInfo + "/#";
var mqttSubscribe = function(topic){
    var defer = $q.defer();

        cordova.plugins.CordovaMqTTPlugin.subscribe({
        topic: topic,
        qos:0,
        success:function(s){

            defer.resolve();
        },
        error:function(e){
            defer.reject();
        }
        });
    return defer.promise;
}
mqttSetupSubscribe(subTopic).then(function(){
cordova.plugins.CordovaMqTTPlugin.listen(subTopic+"serial", 
                function (payload, params, topic, topic_pattern) {
              //you will find a serial key in params object
              alert(JSON.stringify(payload,params,topic));
            });
})
airomyas commented 7 years ago

Thank you very much for your reply. It works for me.