How to reassemble n sequential messages in one?

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.

1 Like

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:
image

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 parts property.

My test flow:

My splitted packets which represent my actual packets to reassemble:

test_flow_splitted_packets

I modified the splitted packets with "Change" node to add the parts property:


test_flow_splitted_packets_with_parts

Here the join of the packets with the parts property:

test_flow_join_with_parts

And the join of the packets without the parts property:

test_flow_join_without_parts

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 msg.payload.parts.
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 msg.payload.

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?

Thanks again.

You can tell the Join node to join as a string.

1 Like

Thank you!

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.

1 Like

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.

1 Like

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.

My flow:

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 [object Object].