1

I am developing a website which can connect to an mqtt broker and get payload messages.

The library I use is (https://eclipse.org/paho/clients/js/).

My problem is the following. When I try to get a standard compressed message (gzipped) the library throw an exception "Error: AMQJS0009E Malformed UTF data:f5 3 -52."

How can I handle compressed messages?

here is my code:

var selected_tags   = '';
var checked_tags    = [];

var hostname        = 'xxx';
var port            = 80;
var qos             = 1;

var user            = 'xxx';
var pass            = 'xxx';

var keepAlive       = 60;
var timeout         = 3;
var ssl             = false;
var cleanSession    = true;
var lastWillTopic   = '';
var lastWillQos     = 1;
var lastWillRetain  = false;
var lastWillMessage = '';
var g_topic;
var client = new Messaging.Client(hostname, port, "myclientid_" + parseInt(Math.random() * 100, 10));

var options = {
    timeout             : 3,
    userName            : user,
    password            : pass,
    keepAliveInterval   : keepAlive,
    cleanSession        : cleanSession,
    useSSL              : ssl,
    onSuccess           : function () {
        console_log('<span style="color:green">Connected</span>');
    },
    onFailure           : function (message) {
        console_log('<span style="color:red">Connection failed: ' + message.errorMessage + '</span>');
        client.connect(options);
    }
};
function _subscribe(){
    g_topic = $("#sel_reader").val();
    console_log('<span style="color:green">subscribe to: ' + g_topic + '</span>');
    client.subscribe(g_topic, {qos: qos});
    $("#_subscribe").addClass('hide');
    $("#_unsubscribe").removeClass('hide');
}
function _unsubscribe(){
    console_log('<span style="color:red">unsubscribe from: ' + g_topic + '</span>');
    client.unsubscribe(g_topic);
    $("#_subscribe").removeClass('hide');
    $("#_unsubscribe").addClass('hide');
}
client.onConnectionLost = function (responseObject) {
    console_log('<span style="color:red">Connection lost: ' + responseObject.errorMessage + '</span>');
    client.connect(options);
};
client.onMessageArrived = function (message) {
    // console.log("message arrived");

    var live_search = [];
    var live_found  = '';
    var json = JSON.parse(message.payloadString);

    console_log('<hr />Message Recieved: Topic: ' + message.destinationName + '<br />' 
                  +message.payloadString + 
                '. QoS: ' + message.qos
    );

};
var publish = function (payload, topic, qos) {
    var message = new Messaging.Message(payload);
    message.destinationName = topic;
    message.qos = qos;
    client.send(message);
}
function console_log(txt){
    $("#console").append('<b>'+txt + "</b><br />");
}
var prev_imei = '';
var find = ':';
var re   = new RegExp(find, 'g');
function SortByRssi(a, b){
    var arssi = a.rssi;
    var brssi = b.rssi; 
    return ((arssi > brssi) ? -1 : ((arssi < brssi) ? 1 : 0));
}
$(document).ready(function(){
    client.connect(options);
});

2 Answers2

3

In case someone needs the answer for Python:

import zlib

def _on_message(self, mqttc, obj, msg):
    dec_msg = zlib.decompress(msg.payload)
    # do whatever you need with dec_msg
    print dec_msg
Tomasz
  • 1,001
  • 8
  • 8
  • Consider providing asnwers in language from question tags - your code _may_ or _may not_ be useful to the question author. – fen1x Aug 25 '17 at 05:42
  • The question is about working with the Paho Javascript client running in the browser, so this does not answer the question – hardillb Aug 25 '17 at 07:02
  • 1
    I agree with you, but on the other hand when I was looking to get the answer for python, I could not find anything. Google bring me to this topic, so maybe one day someone also find it here. – Tomasz Sep 01 '17 at 06:32
0

OK, so there is no built in handling of gzip compressed payloads in MQTT or the Paho Javascript client.

This means when your code runs it tries to parse a gzip stream as a UTF-8 string.

client.onMessageArrived = function (message) {
    // console.log("message arrived");

    var live_search = [];
    var live_found  = '';
    var json = JSON.parse(message.payloadString);

    console_log('<hr />Message Recieved: Topic: ' + message.destinationName + '<br />' 
                  +message.payloadString + 
                '. QoS: ' + message.qos
    );
};

To start with you need to work with the raw bytes not the string form of the message. You can access the raw bytes fromt the message.payloadBytes field.

Now you have the problem of actually decompressing it. This older question looks like it would help.

client.onMessageArrived = function (message) {
    // console.log("message arrived");

    var live_search = [];
    var live_found  = '';
    var compressedJSON = message.payloadBytes;
    var json = pako.inflate(compressedJSON);
    console.log('<hr />Message Recieved: Topic: ' + message.destinationName + '<br />' 
              + json + 
            '. QoS: ' + message.qos
    );
};
Community
  • 1
  • 1
hardillb
  • 54,545
  • 11
  • 67
  • 105