You are reading a single comment by @Moray and its replies. Click here to read the full conversation.
  • I put some debugging code into a copy of TinyMQTT.js, and in each case with the problem MQTT messages the first byte of data (or sometimes the first two bytes of data) is/are missing.

    Good receipt:

    cmd 3 / 30:16:0:10:Coffeemaker/brewbrew

    Bad receipt, it is received as two separate calls to the data handler in TinyMQTT (onDat):

    cmd 3 / 30:0:0:0:
    cmd 1 / 16:0:10:43:offeemaker/brewbrew

    We can see that if these were received in a single call to onDat, the publish command would be good.

    Looking at the code for TinyMQTT, I don't think the issue can be in there, it must be somewhere else - any thoughts on where to look next? Or any thoughts on a sensible workaround, maybe compelling the socket to wait a little longer for data somehow - but looks like that code is maybe built into the firmware in the net module.

    In the meantime I have put in a horrible hack so that if it is a publish command (3) with a total length of less than 5 bytes - which should never happen in my setup - then it stores up to 4 bytes in state waiting for the next call, and prepends these to the second set of data it receives.

    Here is the hacked replacement onDat function for TinyMQTT.js

    function onDat(data) {
    	var i; 
    	//var log="MQTT receiving ";
    	if (_q.tmp != null) {
    		//log += ' APPLYING STORED DATA ';
    		data = _q.tmp + data;
    		_q.tmp = null;
    	}
    	
    	var length = data.length;
    	var cmd = data.charCodeAt(0) >> 4;
    	//log += " length " + data.length + " cmd " + cmd.toString() + " / ";
    	
    	if (cmd ===3 && length <5) {
    		_q.tmp = data;
    		//console.log(log + " STORING EXTRA DATA FOR NEXT TRANSMIT");
    		return;
    	}
    	
    	//for(i=0;i<4;i++) {
    	//	log = log + data.charCodeAt(i).toString(16) + ":";
    	//}
    	//log += data.substr(4,256);
    	//console.log(log);
    	//log = "";
    	if(cmd === 3) {
    		var var_len = data.charCodeAt(2) << 8 | data.charCodeAt(3);
    		var msg = {
    			topic: data.substr(4, var_len),
    			message: data.substr(4+var_len, (data.charCodeAt(1))-var_len)
    		};
    		_q.emit("message", msg);
    	}
    }
    
    

    All kinds of things could go wrong with this approach, especially if new messages are received in quick succession so I don't really want to live with it long-term.

About

Avatar for Moray @Moray started