Node-Red: Create server and share input

2019-09-10 08:19发布

问题:

I'm trying to create a new node for Node-Red. Basically it is a udp listening socket that shall be established via a config node and which shall pass all incoming messages to dedicated nodes for processing. This is the basic what I have:

function udpServer(n) {
    RED.nodes.createNode(this, n);
    this.addr = n.host;
    this.port = n.port;

    var node = this;

    var socket = dgram.createSocket('udp4');

    socket.on('listening', function () {
        var address = socket.address();
        logInfo('UDP Server listening on ' + address.address + ":" + address.port);
    });

    socket.on('message', function (message, remote) {
        var bb = new ByteBuffer.fromBinary(message,1,0);
        var CoEdata = decodeCoE(bb);
        if (CoEdata.type == 'digital') { //handle digital output
            // pass to digital handling node
        }
        else if (CoEdata.type == 'analogue'){ //handle analogue output
            // pass to analogue handling node
        }
    });     

    socket.on("error", function (err) {
        logError("Socket error: " + err);
        socket.close();         
    });

    socket.bind({
        address: node.addr,
        port: node.port,
        exclusive: true
    });

    node.on("close", function(done) {
        socket.close();
    });
}
RED.nodes.registerType("myServernode", udpServer);

For the processing node:

function ProcessAnalog(n) {
    RED.nodes.createNode(this, n);
    var node = this;
    this.serverConfig = RED.nodes.getNode(this.server);

    this.channel = n.channel;

    // how do I get the server's message here?

}
RED.nodes.registerType("process-analogue-in", ProcessAnalog);

I can't figure out how to pass the messages that the socket receives to a variable number of processing nodes, i.e. multiple processing nodes shall share on server instance.

==== EDIT for more clarity =====

I want to develop a new set of nodes:

One Server Node:

  • Uses a config-node to create an UDP listening socket
  • Managing the socket connection (close events, error etc)
  • Receives data packages with one to many channels of different data

One to many processing nodes

  • The processing nodes shall share the same connection that the Server Node has established
  • The processing nodes shall handle the messages that the server is emitting
  • Possibly the Node-Red flow would use as many processing Nodes as there are channels in the server's data package

To quote the Node-Red documentation on config-nodes:

A common use of config nodes is to represent a shared connection to a remote system. In that instance, the config node may also be responsible for creating the connection and making it available to the nodes that use the config node. In such cases, the config node should also handle the close event to disconnect when the node is stopped.

As far as I understood this, I make the connection available via this.serverConfig = RED.nodes.getNode(this.server); but I cannot figure out how to pass data, which is received by this connection, to the node that is using this connection.

回答1:

A node has no knowledge of what nodes it is connected to downstream.

The best you can do from the first node is to have 2 outputs and to send digital to one and analogue to the other.

You would do this by passing an array to the node.send() function.

E.g.

//this sends output to just the first output
node.sent([msg,null]);

//this sends output to just the second output
node.send([null,msg]);

Nodes that have receive messagess need to add a listener for input

e.g.

node.on('input', function(msg) {
   ...
});

All of this is well documented on the Node-RED page

The other option is if the udpServer node is a config node then you need to implement your own listeners, best bet is to look something like the MQTT nodes in core for examples of pooling connections