Aggiungi timeout esplicito al connect TCP

master
Guido Longoni 2026-05-06 12:29:21 +02:00
parent 756038525c
commit 2a3db3ca4b
1 changed files with 36 additions and 6 deletions

View File

@ -38,6 +38,18 @@ module.exports = function(RED) {
} }
} }
function startConnectTimeout(socket, timeout, onTimeout) {
if (timeout === null || timeout <= 0) {
return null;
}
return setTimeout(function() {
if (!socket.destroyed) {
onTimeout();
socket.destroy();
}
}, timeout);
}
/** /**
* Enqueue `item` in `queue` * Enqueue `item` in `queue`
* @param {Denque} queue - Queue * @param {Denque} queue - Queue
@ -86,7 +98,9 @@ module.exports = function(RED) {
node.log(RED._("tcpin.status.connecting",{host:node.host,port:node.port})); node.log(RED._("tcpin.status.connecting",{host:node.host,port:node.port}));
node.status({fill:"grey",shape:"dot",text:"common.status.connecting"}); node.status({fill:"grey",shape:"dot",text:"common.status.connecting"});
var id = (1+Math.random()*4294967295).toString(16); var id = (1+Math.random()*4294967295).toString(16);
var connectTimeout;
client = net.connect(node.port, node.host, function() { client = net.connect(node.port, node.host, function() {
clearTimeout(connectTimeout);
buffer = (node.datatype == 'buffer') ? Buffer.alloc(0) : ""; buffer = (node.datatype == 'buffer') ? Buffer.alloc(0) : "";
node.connected = true; node.connected = true;
node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port})); node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port}));
@ -94,6 +108,9 @@ module.exports = function(RED) {
}); });
client.setKeepAlive(true, node.keepalive); client.setKeepAlive(true, node.keepalive);
applySocketTimeout(client, node.socketTimeout); applySocketTimeout(client, node.socketTimeout);
connectTimeout = startConnectTimeout(client, node.socketTimeout, function() {
node.log(RED._("tcpin.errors.timeout",{port:node.port}));
});
connectionPool[id] = client; connectionPool[id] = client;
client.on('data', function (data) { client.on('data', function (data) {
@ -140,6 +157,7 @@ module.exports = function(RED) {
client.destroy(); client.destroy();
}); });
client.on('close', function() { client.on('close', function() {
clearTimeout(connectTimeout);
delete connectionPool[id]; delete connectionPool[id];
node.connected = false; node.connected = false;
node.status({fill:"red",shape:"ring",text:"common.status.disconnected"}); node.status({fill:"red",shape:"ring",text:"common.status.disconnected"});
@ -300,13 +318,18 @@ module.exports = function(RED) {
var setupTcpClient = function() { var setupTcpClient = function() {
node.log(RED._("tcpin.status.connecting",{host:node.host,port:node.port})); node.log(RED._("tcpin.status.connecting",{host:node.host,port:node.port}));
node.status({fill:"grey",shape:"dot",text:"common.status.connecting"}); node.status({fill:"grey",shape:"dot",text:"common.status.connecting"});
var connectTimeout;
client = net.connect(node.port, node.host, function() { client = net.connect(node.port, node.host, function() {
clearTimeout(connectTimeout);
node.connected = true; node.connected = true;
node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port})); node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port}));
node.status({fill:"green",shape:"dot",text:"common.status.connected"}); node.status({fill:"green",shape:"dot",text:"common.status.connected"});
}); });
client.setKeepAlive(true,120000); client.setKeepAlive(true,120000);
applySocketTimeout(client, node.socketTimeout); applySocketTimeout(client, node.socketTimeout);
connectTimeout = startConnectTimeout(client, node.socketTimeout, function() {
node.log(RED._("tcpin.errors.timeout",{port:node.port}));
});
client.on('error', function (err) { client.on('error', function (err) {
node.log(RED._("tcpin.errors.error",{error:err.toString()})); node.log(RED._("tcpin.errors.error",{error:err.toString()}));
}); });
@ -319,6 +342,7 @@ module.exports = function(RED) {
client.destroy(); client.destroy();
}); });
client.on('close', function() { client.on('close', function() {
clearTimeout(connectTimeout);
node.status({fill:"red",shape:"ring",text:"common.status.disconnected"}); node.status({fill:"red",shape:"ring",text:"common.status.disconnected"});
node.connected = false; node.connected = false;
client.destroy(); client.destroy();
@ -529,10 +553,18 @@ module.exports = function(RED) {
if (host && port) { if (host && port) {
clients[connection_id].connecting = true; clients[connection_id].connecting = true;
clients[connection_id].connectTimeout = startConnectTimeout(clients[connection_id].client, node.socketTimeout, function() {
if (clients[connection_id]) {
clients[connection_id].connected = clients[connection_id].connecting = false;
node.status({fill:"grey",shape:"dot",text:"tcpin.errors.connect-timeout"});
}
});
clients[connection_id].client.connect(port, host, function() { clients[connection_id].client.connect(port, host, function() {
//node.log(RED._("tcpin.errors.client-connected")); //node.log(RED._("tcpin.errors.client-connected"));
node.status({fill:"green",shape:"dot",text:"common.status.connected"}); node.status({fill:"green",shape:"dot",text:"common.status.connected"});
if (clients[connection_id] && clients[connection_id].client) { if (clients[connection_id] && clients[connection_id].client) {
clearTimeout(clients[connection_id].connectTimeout);
clients[connection_id].connectTimeout = null;
clients[connection_id].connected = true; clients[connection_id].connected = true;
clients[connection_id].connecting = false; clients[connection_id].connecting = false;
let event; let event;
@ -648,6 +680,8 @@ module.exports = function(RED) {
clients[connection_id].client.on('close', function() { clients[connection_id].client.on('close', function() {
//console.log("CLOSE"); //console.log("CLOSE");
if (clients[connection_id]) { if (clients[connection_id]) {
clearTimeout(clients[connection_id].connectTimeout);
clients[connection_id].connectTimeout = null;
clients[connection_id].connected = clients[connection_id].connecting = false; clients[connection_id].connected = clients[connection_id].connecting = false;
} }
@ -670,6 +704,7 @@ module.exports = function(RED) {
node.status({fill:"red",shape:"ring",text:"common.status.error"}); node.status({fill:"red",shape:"ring",text:"common.status.error"});
node.error(RED._("tcpin.errors.connect-fail") + " " + connection_id, msg); node.error(RED._("tcpin.errors.connect-fail") + " " + connection_id, msg);
if (clients[connection_id] && clients[connection_id].client) { if (clients[connection_id] && clients[connection_id].client) {
clearTimeout(clients[connection_id].connectTimeout);
clients[connection_id].client.destroy(); clients[connection_id].client.destroy();
delete clients[connection_id]; delete clients[connection_id];
} }
@ -682,12 +717,7 @@ module.exports = function(RED) {
node.status({fill:"grey",shape:"dot",text:"tcpin.errors.connect-timeout"}); node.status({fill:"grey",shape:"dot",text:"tcpin.errors.connect-timeout"});
//node.warn(RED._("tcpin.errors.connect-timeout")); //node.warn(RED._("tcpin.errors.connect-timeout"));
if (clients[connection_id].client) { if (clients[connection_id].client) {
clients[connection_id].connecting = true; clients[connection_id].client.destroy();
clients[connection_id].client.connect(port, host, function() {
clients[connection_id].connected = true;
clients[connection_id].connecting = false;
node.status({fill:"green",shape:"dot",text:"common.status.connected"});
});
} }
} }
}); });