How to detect if net.Socket connection dies - node.js

Viewed 10564

Background

I am communicating with a machine using net.Socket via TCP/IP.

I am able to establish the connection and to send and receive packets of Buffers, which is all fine.

Problem

The problem is that if I manually disconnect the internet cable from the machine, my Node.js connection doesn't fire the close event and I have no means to know if something failed!

Code

let socket;

const start = async function ( config ) {

    await connecToBarrier( config )
        .then( () => console.log( "connected to barrrier" ) )
        .catch( err => {
            throw new Error( `Cannot connect to barrier: ${err}` );
        } );
};

const connecToBarrier = function ( connectOpts ) {
    return new Promise( ( resolve, reject ) => {
        //connectOpts is an object with 'port' and 'host'
        socket = net.createConnection( connectOpts, () => {
            //once I receive a 'hello world' from the machine, I can continue
            socket.once( "data", () => resolve() );
        } );

        socket.on( "connection", () => {
            console.log("onConnection says we have someone!");
        } );

        socket.on( "error", err => {
            console.log(`onError says: ${err}`);
            reject(err);
        } );

        socket.on( "timeout", () => {
            console.log("onTimeout says nothing");
            reject();
        } );

        socket.on( "end", () => {
            console.log("onEnd says nothing");
            reject();
        } );

        socket.on( "close", err => {
            console.log(`onClose says: ${err}`);
            reject(err);
        } );
    } );
};


start();

Research

@robertklep mentioned the setKeepAlive option, however according to

How to test socket.setKeepAlive in NodeJS

it doesn't work. A more profound research shows that this is highly dependant on the Operative System you are using, as per https://stackoverflow.com/a/18678494/1337392

So in other words, unless I am willing to wait several minutes for my heartbeats to actually do something, I don't see a way out of this.

Question

How do I detect if a connection died?

2 Answers

I had the same issue. I ended up doing this as a fix:

const _connect = () => {
  const socket = new net.Socket();
    socket.connect(this.port, this.host);
    socket.setTimeout(10000);

    socket.on('timeout', () => {
        socket.destroy();
        _connect(); 
    });
}

Related