Search code examples
node.jssocketstimeout

node net socket connection timeout


I noticed, that my node server's net.createConnection() has a very long timeout before firing an error on some occasions (seems to be a particular problem with ports...)

i tried to connect to somedomain:9000 (listening, connecting and working as expected) and to somedomain:1234 (same domain, different port, waiting around 2 minutes until "connect ETIMEDOUT")

When i connect to non-existent domains, i get an error right away, but not if i connect to unreachable ports on reachable hosts. i need to determine if a machine is reachable in <1sec..

how do i handle this? Must be some way to notice an unreachable port in under 2minutes? at least some kind of timeout that just sets the address as unreachable after a set amout of time?

Thanks

UPDATE: current Connection code:

this.openConnection = function() {
    try {
        console.log("[INFO] connecting to " + device.ip + ":" + device.port);
        device.clientSocket = new net.createConnection(this.port,this.ip)
            .on('connect', device.connected)
            .on('data', device.inputReceived)
            .on('error', function(err) {

                if (err.code == "ENOTFOUND") {
                    console.log("[ERROR] No device found at this address!");
                    device.clientSocket.destroy();
                    return;
                }

                if (err.code == "ECONNREFUSED") {
                    console.log("[ERROR] Connection refused! Please check the IP.");
                    device.clientSocket.destroy();
                    return;
                }


                console.log("[CONNECTION] Unexpected error! " + err.message + "     RESTARTING SERVER");


                process.exit(1);

            })
            .on('disconnect', function() {
                console.log("[CONNECTION] disconnected!");
            });
    } catch(err) {
        console.log("[CONNECTION] connection failed! " + err);
    }
};

Solution

  • When you connect, you can just set your own timer for whatever timeout you want and if the connect has not succeeded when that timer fires, then it did not succeed as quickly as you want.

    This could be encapsulated in a single function with a single callback or returning a promise.


    Based on your code, here's a shot at adding a timeout to it (untested code):

    this.openConnection = function(timeout) {
        var timer;
        timeout = timeout || 2000;
        try {
            console.log("[INFO] connecting to " + device.ip + ":" + device.port);
            device.clientSocket = new net.createConnection(this.port,this.ip)
                .on('connect', function() {
                    clearTimeout(timer);
                    device.connected();
                })
                .on('data', function() {
                    clearTimeout(timer);
                    device.inputReceived();
                })
                .on('error', function(err) {
                    clearTimeout(timer);
                    if (err.code == "ENOTFOUND") {
                        console.log("[ERROR] No device found at this address!");
                        device.clientSocket.destroy();
                        return;
                    }
    
                    if (err.code == "ECONNREFUSED") {
                        console.log("[ERROR] Connection refused! Please check the IP.");
                        device.clientSocket.destroy();
                        return;
                    }
    
    
                    console.log("[CONNECTION] Unexpected error! " + err.message + "     RESTARTING SERVER");
    
    
                    process.exit(1);
    
                })
                .on('close', function() {
                    console.log("[CONNECTION] disconnected!");
                });
            timer = setTimeout(function() {
                console.log("[ERROR] Attempt at connection exceeded timeout value");
                device.clientSocket.end();
            }, timeout);
        } catch(err) {
            console.log("[CONNECTION] connection failed! " + err);
        }
    };