In my flow (v.1.3.5) I receive sequential MQTT messages that represent fragments of a bigger packet. In the messages I have the info of which number of fragment is. How can I reassemble the fragments in the original packet? What's the best method?
Do you also know how many fragments there are? Or does the last one have some flag to let you know? What type of data are the fragments - strings?
Depending on the details you could use the Join node to do this.
If you configure the Join node in manual mode, you'll see a number of options for how it should combine the incoming messages.
You may find you also need to set
msg.parts on each message containing the right meta data for the Join node to know what to do.
The best thing to do would be to play with the Split node (which does the opposite of the Join node) and can turn a single message into a stream of messages. It sets
msg.parts on each message in the stream - have a look at that to see what you could try emulating with your incoming mqtt messages.
Do you also know how many fragments there are?
Yes. The fragments are basically a json where there are names which values are the number of the actual fragment and the total number of fragments.
There is also a name for the data of fragment which value is a string (I want recompose a huge string that is a base64 image).
I'm a novice with Node-Red but I get what do you mean with Join node. I noticed that there is a "After a number of message parts". I should focus on it?
The idea is that you use the
join node in automatic mode and that you extend the mqtt output (e.g. in
change node) with a
msg.parts property so that
join node knows how to automatically join it.
Here below an example of how the
parts property in the
msg must look like:
I read about the message sequences and the
msg.parts and tried to run an example but I can't see difference between the automatic join with and without
My test flow:
My splitted packets which represent my actual packets to reassemble:
I modified the splitted packets with "Change" node to add the
Here the join of the packets with the
And the join of the packets without the
There is no difference. What am I doing wrong?
And another point: if I add splitted packets with different
parts.id the join continue to output a single array .
You have put the
parts property in the
msg.payload, this is not the correct location. you should put it directly in the
msg => so
msg.parts and not
The join node in automatic node is requiring
msg.parts so that it knows how to automatically join the parts !
Note that your
split node will also set
msg.parts but that is not visible in your debug output as you are only outputting
I got it, now it works! Thanks very much.
Last question: now I have an array with my packets data ordered but how can I concatenate the items (strings) of the array to obtain a single string?
You can tell the Join node to join as a string.
Sorry but I miss something. If I want tell to the Join node to join as a string, I need to set it in manual mode and choose "a String" in "to create" field. But if I set the Join node to manual it seems to loss the ordering of packets according to the
parts.index value, instead concatenate the strings according to the receiving order.
If I use the Join node in automatic mode the ordering is ok but in array with separate items.
What'd I miss?
I couldn't remember all the nuances of the manual-vs-automatic mode in the Join node.
If you want to keep the Join node in automatic mode, then you can set:
msg.parts.type = "string" msg.parts.ch = ""
On each message and the Join node should do what you want.
It works now! Thank you. I thing to understand the
msg.parts.type property but what about
msg.parts.ch? Can you explain it briefly?
Anyway, thank you very much.
msg.parts.ch is the character used to join the string fragments together. By default it uses
"\n" as it assumes you have split multiple lines of text into individual lines.
Sorry guys but I'm here again cause I tried to apply the test flow above to my actual project but I haven't the same result.
and my outputs (the first one the packet changed and the second one the packet joined):
As you can see, the joined packet is a string with
[object Object] repeated for every packet incoming. I've used the same teory of the test flow, the only difference is that now I receive the packets from a mqtt and json nodes. Where did the
[object Object] come from?
Why are you passing it through a JSON node? I thought each message contained a partial fragment of JSON that you needed to recombine into a single string before it could be parsed.
The problem comes because you are converting each JSON string to an Object, then telling the Join node to join them as Strings. And if you
toString an Object you get