From 2a3db3ca4b55204ab4c46d53e49d0359a591122b Mon Sep 17 00:00:00 2001 From: Guido Longoni Date: Wed, 6 May 2026 12:29:21 +0200 Subject: [PATCH] Aggiungi timeout esplicito al connect TCP --- red/tcp/tcp.js | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/red/tcp/tcp.js b/red/tcp/tcp.js index 74258fd..f6f62fb 100644 --- a/red/tcp/tcp.js +++ b/red/tcp/tcp.js @@ -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` * @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.status({fill:"grey",shape:"dot",text:"common.status.connecting"}); var id = (1+Math.random()*4294967295).toString(16); + var connectTimeout; client = net.connect(node.port, node.host, function() { + clearTimeout(connectTimeout); buffer = (node.datatype == 'buffer') ? Buffer.alloc(0) : ""; node.connected = true; 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); applySocketTimeout(client, node.socketTimeout); + connectTimeout = startConnectTimeout(client, node.socketTimeout, function() { + node.log(RED._("tcpin.errors.timeout",{port:node.port})); + }); connectionPool[id] = client; client.on('data', function (data) { @@ -140,6 +157,7 @@ module.exports = function(RED) { client.destroy(); }); client.on('close', function() { + clearTimeout(connectTimeout); delete connectionPool[id]; node.connected = false; node.status({fill:"red",shape:"ring",text:"common.status.disconnected"}); @@ -300,13 +318,18 @@ module.exports = function(RED) { var setupTcpClient = function() { node.log(RED._("tcpin.status.connecting",{host:node.host,port:node.port})); node.status({fill:"grey",shape:"dot",text:"common.status.connecting"}); + var connectTimeout; client = net.connect(node.port, node.host, function() { + clearTimeout(connectTimeout); node.connected = true; node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port})); node.status({fill:"green",shape:"dot",text:"common.status.connected"}); }); client.setKeepAlive(true,120000); applySocketTimeout(client, node.socketTimeout); + connectTimeout = startConnectTimeout(client, node.socketTimeout, function() { + node.log(RED._("tcpin.errors.timeout",{port:node.port})); + }); client.on('error', function (err) { node.log(RED._("tcpin.errors.error",{error:err.toString()})); }); @@ -319,6 +342,7 @@ module.exports = function(RED) { client.destroy(); }); client.on('close', function() { + clearTimeout(connectTimeout); node.status({fill:"red",shape:"ring",text:"common.status.disconnected"}); node.connected = false; client.destroy(); @@ -529,10 +553,18 @@ module.exports = function(RED) { if (host && port) { 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() { //node.log(RED._("tcpin.errors.client-connected")); node.status({fill:"green",shape:"dot",text:"common.status.connected"}); 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].connecting = false; let event; @@ -648,6 +680,8 @@ module.exports = function(RED) { clients[connection_id].client.on('close', function() { //console.log("CLOSE"); if (clients[connection_id]) { + clearTimeout(clients[connection_id].connectTimeout); + clients[connection_id].connectTimeout = null; 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.error(RED._("tcpin.errors.connect-fail") + " " + connection_id, msg); if (clients[connection_id] && clients[connection_id].client) { + clearTimeout(clients[connection_id].connectTimeout); clients[connection_id].client.destroy(); delete clients[connection_id]; } @@ -682,12 +717,7 @@ module.exports = function(RED) { node.status({fill:"grey",shape:"dot",text:"tcpin.errors.connect-timeout"}); //node.warn(RED._("tcpin.errors.connect-timeout")); if (clients[connection_id].client) { - clients[connection_id].connecting = true; - 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"}); - }); + clients[connection_id].client.destroy(); } } });