Sending whole message using MQTT

When I want to send a whole message to another NR instance, I use MQTT and put this blockly node in front of the MQTT out node to "shift" the whole message into msg.payload

image

translates into

image

but I'm wondering if we all doing something similar and whether there's a nicer/better way?

[POST edited to be general discussion on the subject]

Actually, you should also attempt to remove msg.res and msg.req I think as neither of those can be serialised. They are added by ExpressJS so you get them from http-request and http-in nodes for example.

Another issue is that when you delete from the msg object, because msg isn't actually a message but rather a shared memory space (because JavaScript objects are passed by reference), delete can have an impact on other points in your flow. That is why a node with 2 wires on an output automatically creates a clone of the msg object. And you can force that in a change node too.

Ah, gotta love JavaScript's oddities!

But to answer your question directly: speaking personally, I don't ever pass a whole message object :grin:

1 Like

So does this look OK then?
image

I'm afraid not.

const msg2 = RED.util.cloneMessage(msg)
delete msg2._msgid
delete msg2.res
delete msg2.req
return { payload: msg2 }

OK Obiwan - what's the diff? :slight_smile:

Well my Padawan ... :mage:

You need to make a clone before deleting from it otherwise you've already messed up the main msg by the time you come to clone it.

That's it.

aah - I get you Master :slight_smile:

Good, now put that light sabre away before you hurt someone!

2 Likes

image

And just looking at a message I'm sending - I've noticed something called _event that I'm thinking should maybe also be deleted before sending?

image

Question - how can I add all the current flow contexts to msg2?

e.g. set a msg2.payload.flow to { all the flow contexts }

Never seen that so I don't know what sets it. If you are concerned, you might need to delete any property that starts with an _. Though that can be a bit dangerous since nodes might be using that naming convention simply to indicate that the property is specific to the node.

Accessing all flow contexts (unless you know them) is turned off by default I believe. You can turn it on in settings (or is that just for globals, to be honest, can't quite remember). Checked the docs :grin:

const c = {}
flow.keys().forEach( key => {
  c[key] = flow.get(key)
})

msg.payload = c

return msg
1 Like

Had to adapt your solution for Blockly but used your principle :slight_smile:

image

I'm now thinking that it might be nice to make a proper contrib node for this :slight_smile:

1 Like

And you may as well delete topic, retain and qos as they are redundant.. given the many possible things you may or may not want to pass I’m not sure a specific node gains you much (apart from a lot of fun trying to get the ui right to select and delete properties)

1 Like

I'm thinking that my original concept of just removing _msgid is the right approach.

It's the only msg property that I think would actually cause a problem if restored on the receiving end

I came up with this node to save having to worry about what was in the message and just pass it to another instance like any node passes on the msg object to any one connected to it in the same flow

I await correction of my faulty thinking :slight_smile:

Well as @TotallyInformation pointed out there are properties you can't "just pass" on, so you DO have to worry about them. That's ok if it's just you and you know that - but if it's a public node you need to handle them gracefully in some manner. (and just deleteing them obviously means the message at the other end isn't the same so the user need to know that), and while you could take a guess at .res and .req any others are purely at the will of the flow (or a node) creator.

_msgid is used for message tracing only so it is actually probably more useful to leave attached if you ever did want to trace messages across multiple systems.

1 Like

My reason for deleting is that I thought it could clash with a message id on the receiving instance (low probability obviously) but are you saying even if it did - it wouldn't be an issue?

Just for clarification on my normal use case

I have one Pi setup to communicate to Alexa - so I use my encode node (and its corresponding decode version) to send messages to/from that Pi from other systems (inc non-NR ones)

So, an example, I send some text to make Alexa talk but I need to specify which device it should talk on

So within the main Pi, messages have msg.deviceName attached to them and all is good and my flows use this info

So, I needed to send both text and deviceName from one computer to another and came up with this idea to just bundle the whole msg into msg.payload and then decode at far end (rather than using MQTT topic)

So, in my mind, it doesn't matter if the message has other, not required msg.xxx objects - I just send everything and the far end "Make Alexa speak nodes" just ignores the extra objects in the same way it ignores them if received directly over a wire

Now, ignoring _msgid - what is the difference between a message with extra stuff going from one node directly to another in a flow and doing the same but message comes from another instance?

re _msgid - correct - it is only used for logging(tracing) - they are not (or shouldn't be) functional in any way - so yes technically if there was a clash then any tracing app may get confused... but so far I'm not aware of any such app apart from people scrolling through logs.

re your use case - yes - perfectly fine - yes you need the info at the other end so you pack it into payload and yes away you go... exactly what I would do (well I would probably do it the other way round and create a new payload object with only the things I wanted to send to prevent leakage of info etc but that's just me)...

So nothing wrong with YOUR use case or approach - I just don't think there is a need for a generic node to try and do this as there are quite a few edge cases which either need to be handled (which is tricky) or not (in which case what's the point) .

2 Likes