1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Add node.send/on to Function node

This commit is contained in:
Nick O'Leary 2015-03-17 13:40:12 +00:00
parent a1dac1e290
commit dd4cec84bf
3 changed files with 72 additions and 35 deletions

View File

@ -39,15 +39,21 @@
<p>The message is passed in as a JavaScript object called <code>msg</code>.</p> <p>The message is passed in as a JavaScript object called <code>msg</code>.</p>
<p>By convention it will have a <code>msg.payload</code> property containing <p>By convention it will have a <code>msg.payload</code> property containing
the body of the message.</p> the body of the message.</p>
<p>If your node need to log anything use the <code>node</code> object: <h4>Logging and Error Handling</h4>
<p>To log any information, or report an error, the following functions are available:</p>
<ul> <ul>
<li>Info: <code>node.log(msg);</code></li> <li><code>node.log("Log")</code></li>
<li>Warning: <code>node.warn(msg);</code></li> <li><code>node.warn("Warning")</code></li>
<li>Error: <code>node.error(msg);</code></li> <li><code>node.error("Error")</code></li>
</ul> </ul>
</p> </p>
<p>The function should return the messages it wants to pass on to the next nodes <p>The Catch node can also be used to handle errors. To invoke a Catch node,
in the flow. It can return:</p> pass <code>msg</code> as a second argument to <code>node.error</code>:</p>
<pre>node.error("Error",msg)</pre>
<h4>Sending messages</h4>
<p>The function can either return the messages it wants to pass on to the next nodes
in the flow, or can call <code>node.send(messages)</code>.</p>
<p>It can return/send:</p>
<ul> <ul>
<li>a single message object - passed to nodes connected to the first output</li> <li>a single message object - passed to nodes connected to the first output</li>
<li>an array of message objects - passed to nodes connected to the corresponding outputs</li> <li>an array of message objects - passed to nodes connected to the corresponding outputs</li>

View File

@ -19,19 +19,57 @@ module.exports = function(RED) {
var util = require("util"); var util = require("util");
var vm = require("vm"); var vm = require("vm");
function sendResults(node,_msgid,msgs) {
if (msgs == null) {
return;
} else if (!util.isArray(msgs)) {
msgs = [msgs];
}
var msgCount = 0;
for (var m=0;m<msgs.length;m++) {
if (msgs[m]) {
if (util.isArray(msgs[m])) {
for (var n=0; n < msgs[m].length; n++) {
msgs[m][n]._msgid = _msgid;
msgCount++;
}
} else {
msgs[m]._msgid = _msgid;
msgCount++;
}
}
}
if (msgCount>0) {
node.send(msgs);
}
}
function FunctionNode(n) { function FunctionNode(n) {
RED.nodes.createNode(this,n); RED.nodes.createNode(this,n);
var node = this; var node = this;
this.name = n.name; this.name = n.name;
this.func = n.func; this.func = n.func;
var functionText = "var results = null; results = (function(msg){\n"+this.func+"\n})(msg);"; var functionText = "var results = null;"+
"results = (function(msg){ "+
"var __msgid__ = msg._msgid;"+
"var node = {"+
"log:__node__.log,"+
"error:__node__.error,"+
"warn:__node__.warn,"+
"on:__node__.on,"+
"send:function(msgs){ __node__.send(__msgid__,msgs);}"+
"};\n"+
this.func+"\n"+
"})(msg);";
this.topic = n.topic; this.topic = n.topic;
var sandbox = { var sandbox = {
console:console, console:console,
util:util, util:util,
Buffer:Buffer, Buffer:Buffer,
node: { __node__: {
log : function() { log: function() {
node.log.apply(node, arguments); node.log.apply(node, arguments);
}, },
error: function(){ error: function(){
@ -39,11 +77,18 @@ module.exports = function(RED) {
}, },
warn: function() { warn: function() {
node.warn.apply(node, arguments); node.warn.apply(node, arguments);
},
send: function(id,msgs) {
sendResults(node,id,msgs);
},
on: function() {
node.on.apply(node,arguments);
} }
}, },
context: { context: {
global:RED.settings.functionGlobalContext || {} global:RED.settings.functionGlobalContext || {}
} },
setTimeout: setTimeout
}; };
var context = vm.createContext(sandbox); var context = vm.createContext(sandbox);
try { try {
@ -53,26 +98,8 @@ module.exports = function(RED) {
var start = process.hrtime(); var start = process.hrtime();
context.msg = msg; context.msg = msg;
this.script.runInContext(context); this.script.runInContext(context);
var results = context.results; sendResults(this,msg._msgid,context.results);
if (results == null) {
results = [];
} else if (results.length == null) {
results = [results];
}
if (msg._topic) {
for (var m in results) {
if (results[m]) {
if (util.isArray(results[m])) {
for (var n=0; n < results[m].length; n++) {
results[m][n]._topic = msg._topic;
}
} else {
results[m]._topic = msg._topic;
}
}
}
}
this.send(results);
var duration = process.hrtime(start); var duration = process.hrtime(start);
var converted = Math.floor((duration[0]* 1e9 + duration[1])/10000)/100; var converted = Math.floor((duration[0]* 1e9 + duration[1])/10000)/100;
this.metric("duration", msg, converted); this.metric("duration", msg, converted);

View File

@ -105,13 +105,17 @@ describe('function node', function() {
var count = 0; var count = 0;
n2.on("input", function(msg) { n2.on("input", function(msg) {
count++; count++;
try {
should(msg).have.property('payload', count); should(msg).have.property('payload', count);
should(msg).have.property('_topic', 'baz'); should(msg).have.property('_msgid', 1234);
if (count == 2) { if (count == 2) {
done(); done();
} }
} catch(err) {
done(err);
}
}); });
n1.receive({payload:"foo", topic: "bar", _topic:"baz"}); n1.receive({payload:"foo", topic: "bar",_msgid:1234});
}); });
}); });