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

Add TCP request node to TCP node "family"

This commit is contained in:
Dave C-J 2014-07-08 13:45:00 +01:00
parent 2c5d5148b8
commit c10c687653
2 changed files with 198 additions and 15 deletions

View File

@ -57,8 +57,8 @@
</script> </script>
<script type="text/x-red" data-help-name="tcp in"> <script type="text/x-red" data-help-name="tcp in">
<p>Provides a choice of tcp inputs. Can either connect to a remote tcp port, <p>Provides a choice of tcp inputs. Can either connect to a remote tcp port,
or accept incoming connections.</p> or accept incoming connections.</p>
</script> </script>
<script type="text/javascript"> <script type="text/javascript">
@ -115,6 +115,7 @@
}); });
</script> </script>
<script type="text/x-red" data-template-name="tcp out"> <script type="text/x-red" data-template-name="tcp out">
<div class="form-row"> <div class="form-row">
<label for="node-input-beserver"><i class="icon-resize-small"></i> Type</label> <label for="node-input-beserver"><i class="icon-resize-small"></i> Type</label>
@ -143,12 +144,12 @@
</script> </script>
<script type="text/x-red" data-help-name="tcp out"> <script type="text/x-red" data-help-name="tcp out">
<p>Provides a choice of tcp outputs. Can either connect to a remote tcp port, <p>Provides a choice of tcp outputs. Can either connect to a remote tcp port,
accept incoming connections, or reply to messages received from a TCP In node.</p> accept incoming connections, or reply to messages received from a TCP In node.</p>
<p>Only <b>msg.payload</b> is sent.</p> <p>Only <b>msg.payload</b> is sent.</p>
<p>If <b>msg.payload</b> is a string containing a base64 encoding of binary <p>If <b>msg.payload</b> is a string containing a base64 encoding of binary
data, the Base64 decoding option will cause it to be converted back to binary data, the Base64 decoding option will cause it to be converted back to binary
before being sent.</p> before being sent.</p>
</script> </script>
<script type="text/javascript"> <script type="text/javascript">
@ -193,3 +194,75 @@
} }
}); });
</script> </script>
<script type="text/x-red" data-template-name="tcp request">
<div class="form-row">
<label for="node-input-server"><i class="fa fa-globe"></i> Server</label>
<input type="text" id="node-input-server" placeholder="ip.address" style="width:50%">
&nbsp;port <input type="text" id="node-input-port" style="width:50px">
</div>
<div class="form-row">
<label for="node-input-out"><i class="fa fa-sign-out"></i> Return</label>
<select type="text" id="node-input-out" style="width:52%;">
<option value="time">after a fixed timeout of</option>
<option value="char">when character received is</option>
<option value="count">a fixed number of characters</option>
</select>
<input type="text" id="node-input-splitc" style="width:50px;">
<span id="node-units"></span>
</div>
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-tips"><b>Tip:</b> outputs a binary <b>Buffer</b>, so you may want to .toString() it.</div>
<script>
var previous = null;
$("#node-input-out").on('focus', function () { previous = this.value; }).change(function() {
if (previous == null) { previous = $("#node-input-out").val(); }
if ($("#node-input-out").val() == "char") {
if (previous != "char") $("#node-input-splitc").val("\\n");
$("#node-units").text("");
}
else if ($("#node-input-out").val() == "time") {
if (previous != "time") $("#node-input-splitc").val("0");
$("#node-units").text("ms");
}
else {
if (previous != "count") $("#node-input-splitc").val("12");
$("#node-units").text("chars");
}
});
</script>
<script type="text/x-red" data-help-name="tcp request">
<p>A simple TCP request node - sends the <b>msg.payload</b> to a server tcp port and expects a response.</p>
<p>Connects, sends the "request", reads the "response" and disconnects. It can either count a number of
returned characters into a fixed buffer, match a specified character before returning,
or wait a fixed timeout from first reply and then return.</p>
<p>The response will be output in <b>msg.payload</b> as a buffer, so you may want to .toString() it.</p>
</script>
<script type="text/javascript">
RED.nodes.registerType('tcp request',{
category: 'function',
color:"Silver",
defaults: {
server: {value:"",required:true},
port: {value:"",required:true,validate:RED.validators.number()},
out: {value:"time",required:true},
splitc: {value:"0",required:true},
name: {value:""}
},
inputs:1,
outputs:1,
icon: "bridge-dash.png",
label: function() {
return this.name || "tcp:"+(this.server?this.server+":":"")+this.port;
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>

View File

@ -309,6 +309,116 @@ module.exports = function(RED) {
}); });
} }
} }
RED.nodes.registerType("tcp out",TcpOut); RED.nodes.registerType("tcp out",TcpOut);
function TcpGet(n) {
RED.nodes.createNode(this,n);
this.server = n.server;
this.port = Number(n.port);
this.out = n.out;
this.splitc = n.splitc;
if (this.out != "char") { this.splitc = Number(this.splitc); }
else { this.splitc.replace("\\n","\n").replace("\\r","\r").replace("\\t","\t").replace("\\e","\e").replace("\\f","\f").replace("\\0","\0"); }
var buf;
if (this.out == "count") { buf = new Buffer(this.splitc); }
else { buf = new Buffer(32768); } // set it to 32k... hopefully big enough for most.... but only hopefully
var node = this;
var client;
this.on("input", function(msg) {
var i = 0;
if (!(msg.payload instanceof Buffer)) {
msg.payload = msg.payload.toString();
}
client = net.Socket();
client.setTimeout(socketTimeout);
client.connect(node.port, node.server, function() {
//node.log('client connected');
client.write(msg.payload);
});
client.on('data', function(data) {
//node.log("data", data.length, data);
if (node.splitc === 0) {
node.send({"payload": data});
}
else {
for (var j = 0; j < data.length; j++ ) {
if (node.out == "time") {
// do the timer thing
if (node.tout) {
i += 1;
buf[i] = data[j];
}
else {
node.tout = setTimeout(function () {
node.tout = null;
var m = new Buffer(i+1);
buf.copy(m,0,0,i+1);
node.send({"payload": m});
client.end();
m = null;
}, node.splitc);
i = 0;
buf[0] = data[j];
}
}
// count bytes into a buffer...
else if (node.out == "count") {
buf[i] = data[j];
i += 1;
if ( i >= node.serialConfig.count) {
node.send({"payload": buf});
client.end();
i = 0;
}
}
// look for a char
else {
buf[i] = data[j];
i += 1;
if (data[j] == node.splitc) {
var m = new Buffer(i);
buf.copy(m,0,0,i);
node.send({"payload": m});
client.end();
m = null;
i = 0;
}
}
}
}
});
client.on('end', function() {
//node.log('client disconnected');
});
client.on('error', function() {
node.log('connect failed');
if (client) { client.end(); }
});
client.on('timeout',function() {
node.log('connect timeout');
if (client) {
client.end();
setTimeout(function() {
client.connect(node.port, node.server, function() {
//node.log('client connected');
client.write(msg.payload);
});
},reconnectTime);
}
});
});
this.on("close", function() {
if (client) { buf = null; client.end(); }
});
}
RED.nodes.registerType("tcp request",TcpGet);
} }