Creating an async node that uses pub/sub

Hello all,

I'd like to create (or ideally use an existing one) a Node-RED node that:

  1. Receives an input.
  2. Publishes a message to either Kafka or MQTT.
  3. Listens to a topic until it receives a response to the original message, processed by an external service.
  4. Writes the response to the output.

Does such a node already exist? Is it possible to create in Node-RED?

# pseudo code: input -> my node -> output

# my node:
id=random()
pub("my_topic_input", id, input)
// other messages may arrive but for other id. They should not be lost as they belongs to other inputs
output = await sub("my_topic_output", id)
return output

None of this requires the development of a new node.

You can create a (reusable) subroutine (via a link-call node) or a subflow containing the necessary existing nodes that do what you are asking.

If your broker is v5 ready (most are) and your end device uses the response topic pattern, you can take advantage of that also.

2 Likes

Where MQTT is not in use (and for general logic)
you can use a combination of change and switch nodes

  • When you send the request
    • Add your ID (that is being sent) to a flow variable (via change node)

Screenshot 2024-09-08 at 10.07.05

Then,... when you're receiving responses back, only pass it through if it matches the recently set ID (via the switch node)

Screenshot 2024-09-08 at 10.08.23

and like @Steve-Mcl said - you can wrap this is in a unit for reuse

Be wary of using context in async things like this. Fast consecutive operations would have concurrency issues. It is doable via arrays or lookup that keep all outbound messages and perform a look up upon response etc. But the link-call mostly takes care of all that.

2 Likes

thanks @Steve-Mcl ,

I've tried with link-call but without success... So the starting point was as simple as

But I've received
Screenshot 2024-09-10 at 12.23.50

So my next temptative was like this:

Trying to keep thosse node informations...

But I'm pretty sure I'm missing something... cannot be so complicated.

Just wondering if it woud be simpler just to code it in a node ?