mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Let UDP node better share same port instance if required
This commit is contained in:
parent
ea8c6d5cce
commit
29e9740668
@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-port"><i class="fa fa-sign-in"></i> <span data-i18n="udp.label.onport"></span></label>
|
<label for="node-input-port"><i class="fa fa-sign-in"></i> <span data-i18n="udp.label.onport"></span></label>
|
||||||
<input type="text" id="node-input-port" style="width: 80px">
|
<input type="text" id="node-input-port" style="width:80px">
|
||||||
<span data-i18n="udp.label.using"></span> <select id="node-input-ipv" style="width:80px">
|
<span data-i18n="udp.label.using"></span> <select id="node-input-ipv" style="width:80px">
|
||||||
<option value="udp4">ipv4</option>
|
<option value="udp4">ipv4</option>
|
||||||
<option value="udp6">ipv6</option>
|
<option value="udp6">ipv6</option>
|
||||||
@ -41,7 +41,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-datatype"><i class="fa fa-sign-out"></i> <span data-i18n="udp.label.output"></span></label>
|
<label for="node-input-datatype"><i class="fa fa-sign-out"></i> <span data-i18n="udp.label.output"></span></label>
|
||||||
<select id="node-input-datatype" style="width: 70%;">
|
<select id="node-input-datatype" style="width:70%;">
|
||||||
<option value="buffer" data-i18n="udp.output.buffer"></option>
|
<option value="buffer" data-i18n="udp.output.buffer"></option>
|
||||||
<option value="utf8" data-i18n="udp.output.string"></option>
|
<option value="utf8" data-i18n="udp.output.string"></option>
|
||||||
<option value="base64" data-i18n="udp.output.base64"></option>
|
<option value="base64" data-i18n="udp.output.base64"></option>
|
||||||
@ -83,7 +83,9 @@
|
|||||||
if (this.multicast=="false") {
|
if (this.multicast=="false") {
|
||||||
return this.name||"udp "+this.port;
|
return this.name||"udp "+this.port;
|
||||||
}
|
}
|
||||||
else return this.name||"udp "+(this.group+":"+this.port);
|
else {
|
||||||
|
return this.name||"udp "+(this.group+":"+this.port);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
labelStyle: function() {
|
labelStyle: function() {
|
||||||
return this.name?"node_label_italic":"";
|
return this.name?"node_label_italic":"";
|
||||||
@ -107,7 +109,7 @@
|
|||||||
var portsInUse = {};
|
var portsInUse = {};
|
||||||
$.getJSON('udp-ports/'+this.id,function(data) {
|
$.getJSON('udp-ports/'+this.id,function(data) {
|
||||||
portsInUse = data || {};
|
portsInUse = data || {};
|
||||||
$('#udpporttip').html(porttip + Object.keys(data||{}));
|
$('#udpporttip').html(porttip + data);
|
||||||
});
|
});
|
||||||
$("#node-input-port").change(function() {
|
$("#node-input-port").change(function() {
|
||||||
var portnew = $("#node-input-port").val();
|
var portnew = $("#node-input-port").val();
|
||||||
@ -129,11 +131,11 @@
|
|||||||
<option value="broad" data-i18n="udp.bcmsg"></option>
|
<option value="broad" data-i18n="udp.bcmsg"></option>
|
||||||
<option value="multi" data-i18n="udp.mcmsg"></option>
|
<option value="multi" data-i18n="udp.mcmsg"></option>
|
||||||
</select>
|
</select>
|
||||||
<span data-i18n="udp.label.toport"></span> <input type="text" id="node-input-port" style="width: 70px">
|
<span data-i18n="udp.label.toport"></span> <input type="text" id="node-input-port" style="width:70px">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row node-input-addr">
|
<div class="form-row node-input-addr">
|
||||||
<label for="node-input-addr" id="node-input-addr-label"><i class="fa fa-list"></i> <span data-i18n="udp.label.address"></span></label>
|
<label for="node-input-addr" id="node-input-addr-label"><i class="fa fa-list"></i> <span data-i18n="udp.label.address"></span></label>
|
||||||
<input type="text" id="node-input-addr" data-i18n="[placeholder]udp.placeholder.address" style="width: 50%;">
|
<input type="text" id="node-input-addr" data-i18n="[placeholder]udp.placeholder.address" style="width:50%;">
|
||||||
<select id="node-input-ipv" style="width:70px">
|
<select id="node-input-ipv" style="width:70px">
|
||||||
<option value="udp4">ipv4</option>
|
<option value="udp4">ipv4</option>
|
||||||
<option value="udp6">ipv6</option>
|
<option value="udp6">ipv6</option>
|
||||||
@ -149,12 +151,12 @@
|
|||||||
<option id="node-input-outport-type-random" value="random" data-i18n="udp.bind.random"></option>
|
<option id="node-input-outport-type-random" value="random" data-i18n="udp.bind.random"></option>
|
||||||
<option value="fixed" data-i18n="udp.bind.local"></option>
|
<option value="fixed" data-i18n="udp.bind.local"></option>
|
||||||
</select>
|
</select>
|
||||||
<input type="text" id="node-input-outport" style="width: 70px;">
|
<input type="text" id="node-input-outport" style="width:70px;">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label> </label>
|
<label> </label>
|
||||||
<input type="checkbox" id="node-input-base64" style="display: inline-block; width: auto; vertical-align: top;">
|
<input type="checkbox" id="node-input-base64" style="display:inline-block; width:auto; vertical-align:top;">
|
||||||
<label for="node-input-base64" style="width: 70%;"><span data-i18n="udp.label.decode-base64"></span></label>
|
<label for="node-input-base64" style="width:70%;"><span data-i18n="udp.label.decode-base64"></span></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||||
@ -201,7 +203,7 @@
|
|||||||
var bindrandom = this._("udp.bind.random");
|
var bindrandom = this._("udp.bind.random");
|
||||||
var bindtarget = this._("udp.bind.target");
|
var bindtarget = this._("udp.bind.target");
|
||||||
|
|
||||||
var type = this.outport==""?"random":"fixed";
|
var type = this.outport===""?"random":"fixed";
|
||||||
$("#node-input-outport-type").val(type);
|
$("#node-input-outport-type").val(type);
|
||||||
|
|
||||||
$("#node-input-outport-type").change(function() {
|
$("#node-input-outport-type").change(function() {
|
||||||
|
@ -29,11 +29,18 @@ module.exports = function(RED) {
|
|||||||
this.multicast = n.multicast;
|
this.multicast = n.multicast;
|
||||||
this.ipv = n.ipv || "udp4";
|
this.ipv = n.ipv || "udp4";
|
||||||
var node = this;
|
var node = this;
|
||||||
|
|
||||||
|
var opts = {type:node.ipv, reuseAddr:true};
|
||||||
|
if (process.version.indexOf("v0.10") === 0) { opts = node.ipv; }
|
||||||
|
var server;
|
||||||
|
|
||||||
if (!udpInputPortsInUse.hasOwnProperty(this.port)) {
|
if (!udpInputPortsInUse.hasOwnProperty(this.port)) {
|
||||||
udpInputPortsInUse[this.port] = n.id;
|
server = dgram.createSocket(opts); // default to udp4
|
||||||
|
udpInputPortsInUse[this.port] = server;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node.warn(RED._("udp.errors.alreadyused",node.port));
|
node.warn(RED._("udp.errors.alreadyused",node.port));
|
||||||
|
server = udpInputPortsInUse[this.port]; // re-use existing
|
||||||
}
|
}
|
||||||
|
|
||||||
var opts = {type:node.ipv, reuseAddr:true};
|
var opts = {type:node.ipv, reuseAddr:true};
|
||||||
@ -83,24 +90,26 @@ module.exports = function(RED) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
node.on("close", function() {
|
node.on("close", function() {
|
||||||
if (udpInputPortsInUse[node.port] === node.id) {
|
if (udpInputPortsInUse.hasOwnProperty(node.port)) {
|
||||||
delete udpInputPortsInUse[node.port];
|
delete udpInputPortsInUse[node.port];
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
server.close();
|
server.close();
|
||||||
node.log(RED._("udp.status.listener-stopped"));
|
node.log(RED._("udp.status.listener-stopped"));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
node.error(err);
|
//node.error(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
server.bind(node.port,node.iface);
|
try { server.bind(node.port,node.iface); }
|
||||||
|
catch(e) { } // Don't worry if already bound
|
||||||
}
|
}
|
||||||
RED.httpAdmin.get('/udp-ports/:id', RED.auth.needsPermission('udp-in.read'), function(req,res) {
|
RED.httpAdmin.get('/udp-ports/:id', RED.auth.needsPermission('udp-in.read'), function(req,res) {
|
||||||
res.json(udpInputPortsInUse);
|
res.json(Object.keys(udpInputPortsInUse));
|
||||||
});
|
});
|
||||||
RED.nodes.registerType("udp in",UDPin);
|
RED.nodes.registerType("udp in",UDPin);
|
||||||
|
|
||||||
|
|
||||||
// The Output Node
|
// The Output Node
|
||||||
function UDPout(n) {
|
function UDPout(n) {
|
||||||
RED.nodes.createNode(this,n);
|
RED.nodes.createNode(this,n);
|
||||||
@ -116,7 +125,15 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
var opts = {type:node.ipv, reuseAddr:true};
|
var opts = {type:node.ipv, reuseAddr:true};
|
||||||
if (process.version.indexOf("v0.10") === 0) { opts = node.ipv; }
|
if (process.version.indexOf("v0.10") === 0) { opts = node.ipv; }
|
||||||
var sock = dgram.createSocket(opts); // default to udp4
|
|
||||||
|
var sock;
|
||||||
|
if (udpInputPortsInUse[this.outport]) {
|
||||||
|
sock = udpInputPortsInUse[this.outport];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sock = dgram.createSocket(opts); // default to udp4
|
||||||
|
udpInputPortsInUse[this.outport] = sock;
|
||||||
|
}
|
||||||
|
|
||||||
sock.on("error", function(err) {
|
sock.on("error", function(err) {
|
||||||
// Any async error will also get reported in the sock.send call.
|
// Any async error will also get reported in the sock.send call.
|
||||||
@ -125,7 +142,7 @@ module.exports = function(RED) {
|
|||||||
// down.
|
// down.
|
||||||
});
|
});
|
||||||
if (node.multicast != "false") {
|
if (node.multicast != "false") {
|
||||||
if (node.outport == "") { node.outport = node.port; }
|
if (node.outport === "") { node.outport = node.port; }
|
||||||
sock.bind(node.outport, function() { // have to bind before you can enable broadcast...
|
sock.bind(node.outport, function() { // have to bind before you can enable broadcast...
|
||||||
sock.setBroadcast(true); // turn on broadcast
|
sock.setBroadcast(true); // turn on broadcast
|
||||||
if (node.multicast == "multi") {
|
if (node.multicast == "multi") {
|
||||||
@ -146,11 +163,9 @@ module.exports = function(RED) {
|
|||||||
node.log(RED._("udp.status.bc-ready",{outport:node.outport,host:node.addr,port:node.port}));
|
node.log(RED._("udp.status.bc-ready",{outport:node.outport,host:node.addr,port:node.port}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (node.outport != "") {
|
} else if ((node.outport !== "") && (!udpInputPortsInUse[this.outport])) {
|
||||||
setTimeout( function() {
|
|
||||||
sock.bind(node.outport);
|
sock.bind(node.outport);
|
||||||
node.log(RED._("udp.status.ready",{outport:node.outport,host:node.addr,port:node.port}));
|
node.log(RED._("udp.status.ready",{outport:node.outport,host:node.addr,port:node.port}));
|
||||||
}, 250);
|
|
||||||
} else {
|
} else {
|
||||||
node.log(RED._("udp.status.ready-nolocal",{host:node.addr,port:node.port}));
|
node.log(RED._("udp.status.ready-nolocal",{host:node.addr,port:node.port}));
|
||||||
}
|
}
|
||||||
@ -159,9 +174,9 @@ module.exports = function(RED) {
|
|||||||
if (msg.hasOwnProperty("payload")) {
|
if (msg.hasOwnProperty("payload")) {
|
||||||
var add = node.addr || msg.ip || "";
|
var add = node.addr || msg.ip || "";
|
||||||
var por = node.port || msg.port || 0;
|
var por = node.port || msg.port || 0;
|
||||||
if (add == "") {
|
if (add === "") {
|
||||||
node.warn(RED._("udp.errors.ip-notset"));
|
node.warn(RED._("udp.errors.ip-notset"));
|
||||||
} else if (por == 0) {
|
} else if (por === 0) {
|
||||||
node.warn(RED._("udp.errors.port-notset"));
|
node.warn(RED._("udp.errors.port-notset"));
|
||||||
} else if (isNaN(por) || (por < 1) || (por > 65535)) {
|
} else if (isNaN(por) || (por < 1) || (por > 65535)) {
|
||||||
node.warn(RED._("udp.errors.port-invalid"));
|
node.warn(RED._("udp.errors.port-invalid"));
|
||||||
@ -185,11 +200,14 @@ module.exports = function(RED) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
node.on("close", function() {
|
node.on("close", function() {
|
||||||
|
if (udpInputPortsInUse.hasOwnProperty(node.outport)) {
|
||||||
|
delete udpInputPortsInUse[node.outport];
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
sock.close();
|
sock.close();
|
||||||
node.log(RED._("udp.status.output-stopped"));
|
node.log(RED._("udp.status.output-stopped"));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
node.error(err);
|
//node.error(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user