Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reconnect net.socket nodejs

I am new to node.js and would like to connect to a TCP socket. For this I am using the net module.

My idea was to wrap the connect sequence into a function then on the 'close' event, attempt a reconnection. Not that easy apparently.

function conn() {

    client.connect(HOST_PORT, HOST_IP, function() {
        startSequence();
    })
}

client.on('close', function(e) {
    log('info','Connection closed! -> ' + e)
    client.destroy();
    setTimeout(conn(),1000);
});

So when the remote host is closed, I see my logs comming through, howere what seems to be happening is that as soons as the remote host comes online ALL the previous attempts start to get processed - if that makes sense. If you look at client.connect, there is a function called startSequence that sends some data that "iniates" the connection from the remote server side. When the server goes offline and I start reconnecting all the failed attempts from before seem to have been buffered and are all sent together when the server goes online.

I have tried the code from this Stackoverflow link as well to no avail (Nodejs - getting client socket to try again after 5 sec time out)

client.connect(HOST_PORT, HOST_IP, function() {
    pmsStartSequence();
})


// Add a 'close' event handler for the client socket
client.on('close', function(e) {
    log('debug','connection  closed -> ' + e)
    client.setTimeout(10000, function() {
        log('debug', 'trying to reconnect')
        client.connect(HOST_PORT, HOST_IP, function() {
            pmsStartSequence();
        })
    })
});

Is there any advice on how I can reconnect a socket after failure?

like image 603
Ryan de Kock Avatar asked Sep 11 '14 15:09

Ryan de Kock


People also ask

Does socket IO reconnect after disconnect?

This event is fired upon disconnection. In the first two cases (explicit disconnection), the client will not try to reconnect and you need to manually call socket.

How do I create a socket server listening for connection on given path?

socket.connect(path[, connectListener]) Opens the connection for a given socket. If port and host are given, then the socket will be opened as a TCP socket, if host is omitted, localhost will be assumed. If a path is given, the socket will be opened as a Unix socket to that path.

How do I socket in node js?

// make a connection with the user from server side io. on('connection', (socket)=>{ console. log('New user connected'); }); Similarly, from the client-side, we need to add a script file and then make a connection to a server through which users send data to a server.

Which node creates the listener socket?

It can also be created by Node. js and passed to the user when a connection is received. For example, it is passed to the listeners of a 'connection' event emitted on a net.


2 Answers

The problem is where you set the on-connect callback.

The doc of socket.connect() says:

connectListener ... will be added as a listener for the 'connect' event once.

By setting it in socket.connect() calls, every time you try reconnecting, one more listener (a one-time one), which calls startSequence(), is attached to that socket. Those listeners will not be fired until reconnection successes, so you got all of them triggered at the same time on a single connect.

One possible solution is separating the connect listener from socket.connect() calls.

client.on('connect', function() {
    pmsStartSequence();
});

client.on('close', function(e) {
    client.setTimeout(10000, function() {
        client.connect(HOST_PORT, HOST_IP);
    })
});

client.connect(HOST_PORT, HOST_IP);
like image 139
ebk Avatar answered Nov 10 '22 01:11

ebk


Inspired from the other solutions, I wrote this, it's tested, it works ! It will keep on trying every 5 sec, until connection is made, works if it looses connection too.

/* Client connection */
/* --------------------------------------------------------------------------------- */

const client = new net.Socket()
var intervalConnect = false;

function connect() {
    client.connect({
        port: 1338,
        host: '127.0.0.1'
    })
}

function launchIntervalConnect() {
    if(false != intervalConnect) return
    intervalConnect = setInterval(connect, 5000)
}

function clearIntervalConnect() {
    if(false == intervalConnect) return
    clearInterval(intervalConnect)
    intervalConnect = false
}

client.on('connect', () => {
    clearIntervalConnect()
    logger('connected to server', 'TCP')
    client.write('CLIENT connected');
})

client.on('error', (err) => {
    logger(err.code, 'TCP ERROR')
    launchIntervalConnect()
})
client.on('close', launchIntervalConnect)
client.on('end', launchIntervalConnect)

connect()
like image 37
Vincent Wasteels Avatar answered Nov 09 '22 23:11

Vincent Wasteels