[New Node] node-red-contrib-events: Alternative to link nodes

As I say, I don't believe that to be a good idea simply because I've not come across any other nodes that treat msg.topic as anything but a string in keeping with its origin with MQTT.

Haha, yes that was already spotted. I'll push another version shortly but unfortunately, it will do weird things to an existing flow :slight_smile:

The new version uses the same naming as other event-based nodes.

1 Like

There had to be a first for every thing.
All moot if there is subscription like mqtt # +.

Julian, if you are interested, the topic matching code in this subflow is fairly well tested - you are free to use it if it helps.

https://flows.nodered.org/flow/e38554543a8cdec6c44eacfc68a0c149

It was off when I'd tried to have topic filtering added to switch node.

I think the one that already exists is node-red-contrib-sub-link

Thanks Steve. I certainly would need to put a basic sanity check on the topic name (probably a string no more than 255 characters). That node might be helpful if I extend the out node to support wild-cards.

Thanks Dave, I've done a quick check of that node. It isn't really clear to me why it needs to be so complex or why it needs a config node. Unusually for me, I was aiming for simplicity in this node. :slight_smile:

One thing I don't know about using events and I don't know how I can test - is the output from an event listener function a CLONE of the input or is it a REFERENCE?

I'd strongly recommend against doing that. You should create your own EventEmitter object that is shared by your nodes and nothing else.

This came up in a thread recently that you contributed to, and I made the same recommendation there: Node Developers: How To use setMaxListeners() using RED.events - #2 by knolleary

No problem Nick, I will change it. It was just quick & dirty to get something going with minimal effort.

Shame though as it would make it available to all nodes as well :slight_smile:


Ah, I remember the other reason now - using the RED event emitter avoids having to create another shared library and allows all nodes, including function nodes I believe, to make use of the evets.

If I have a separate event handler, this is not possible. Which makes the whole thing rather less useful.

But other nodes should not be able to trigger your nodes directly, so that isn't an issue.

I have no issue with your nodes bypassing the wiring to pass messages amongst themselves - but this should not become a shadow-messaging system between arbitrary nodes.

OK, no problem. Changes will be done today.

On balance of this discussion, I think I will probably pubish the package but I'll give it a bit more thought.

(and does some more things)

Ah right - yes that was the one (ok so there are already 2 :slight_smile:

Hmm.

Maybe not so much. They look similar on the surface but they certainly they aren't under the skin.

The topic-link nodes use a pair of internal objects. sub-link requires a config node.

Both require configuration and use MQTT-style wildcards and neither make use of the native event system at all.

The approach I've suggested requires zero configuration and makes use of the native events process and so should be as efficient as it is possible to be. The code is also a lot simpler, though it will have to get a bit more complex to handle the fact that I can't use Node-RED's own event service (I will likely use a singleton class so as to avoid the need for a config node).

So I'm still thinking there may be room for another node. Shoot me down if you think that I'm wrong. I would add references to the other options as well of course.

what kind of configuration does "topic-link" require that "events" doesn't?

Regarding efficiency: If a topic is specified on both in and out nodes, then it is as efficient as possible, since during runtime no search over nodes is necessary.
In case the topic is specified via the message, then it has to loop over all out nodes, which the event emitter class has to do as well. Could still be that the event emitter class is a bit more efficient in this case, but one would has to test.
Using event emitters does not allow wildcards, which was the reason for this implementation.

Apologies, I should have realised that you were the author!

Ah, see what you mean. My bad. I hadn't installed it and I was just reading the code. You are right, no config required.

The topic-link node uses 2 sets and a map to keep track of things I think?

The event node uses the node.js event handler which only requires a string (topic) and an event handler function and all that function does is a send. So no need to keep track of data at all. And no need to loop over anything. The close processing is similarly very simple and takes into account having any number of node instances of any topic.

However, of course, I have not included any wild-card handling and a new day with fresh coffee suggests that maybe that isn't as easy as I thought.

Indeed, I should have remembered, having looked at this recently, that the EventEmitter2 module is what is needed for wildcards and other nice advanced event handling. And it claims to be even faster than the native node.js handler.

The downside of EventEmitter2 is that it only supports '*' as a wildcard, not sure if it would be possible to manipulate that to support MQTT-style wildcards.

The advantage is that it would be fairly easy to add support for subscribing to multiple topics as an array.

No worries!

Yes, those sets and maps are to realize wildcards both in- and out-bound with the advantage of the linking between the nodes happening on deploy (if the topic is set on the node).
Without wildcards, one could get rid of the loop during runtime for the case where one wants to set the topic through the message.

I have pushed a new version of contrib-events, you might want to have a look. It uses the EventEmitter2 node instead of the RED.events and so requires no additional coding to support * wildcards. I've set it to recognise / as a namespace separator just like MQTT. It uses a shared module between the two separate node modules.

2 Likes

There's also node-red-contrib-pubsub (node) - Node-RED which seems to achive the same end result?

Annoying to have to install it to look at the code.

These nodes have no real docs. They manually do what the native event system does for you. They manually convert msg objects to a string and back. The stringify process isn't wrapped in a try/catch which may be a little fragile.

And finally, they don't support wildcard subscriptions.

Currently, @cinhcet's node-red-contrib-topic-link nodes are the closest to mine.

As such, I don't think I will publish these with the node-red tag (assuming I publish them at all) to save any further confusion even though I much prefer my own version here :slight_smile: I will undoubtedly continue to use mine and they will remain on GitHub with some enhancements.

If you want to use my version, please feel free to do so from GitHub. Or contact me direct if you think they should be published. I've added references to the other nodes listed in this thread - many thanks for those people who went digging :mage: - in the readme.

4 Likes

Why don't you collaborate? Labor shared is halved.