ivan R
ivan R

Reputation: 296

socket io creating multiple connection on reload

I am trying to make a socket io push logs to client UI. Here is the code in angular 2

ngAfterViewInit(){
this.socket=io('http://localhost:9999')
    this.socket.on('send-log-data-'+this.labName,function(data){
                this.loaddata(data)
}.bind(this))
}
@HostListener('window:beforeunload', ['$event'])
doSomething($event) {
// if(this.hasChanges) $event.returnValue='Your data will be lost!';
this.socket.emit('disconnect',"")
}
}

After looking in to server side i can see on every reload of web page two new connection are getting created and one connection is getting closed.

On First Reload

new connection made
new connection made
Reloading
Reloading
disonnect request came.Disconnecting

On second reload

Reloading
new connection made
new connection made
new connection made
new connection made
Reloading
Reloading
disonnect request came.Disconnecting
disonnect request came.Disconnecting

Server side code as asked is

    var Tail=require('tail').Tail
module.exports = {

io_connect_disconnect : (labName,io) => {

io.on('connection',function(socket){
    console.log("new connection made")
        filename="output.log"
    var options= {fromBeginning: true}
    tail = new Tail(filename,options)

    console.log("new connection made")
    tail.on("line", function(data) {
        console.log("triggering")
        console.log(data)
io.sockets.emit('send-log-data-'+labName,data)
})
socket.on('disconnect',function(){
    tail.unwatch()
    console.log("disonnect request came.Disconnecting")
    socket.disconnect();
})
})
}
}

Can anyone help me with this strange situation ?

Upvotes: 1

Views: 1201

Answers (1)

Sriram Kailasam
Sriram Kailasam

Reputation: 358

UPDATE:

It's been over 4 years since I wrote this answer, and I realized that this is not a good solution to the problem. There is a more fundamental flaw in your code, and it doesn't have anything to do with io.once() or io.on().

You are only supposed to tail the file once. The code you have posted registers a new Tail instance on every new connection, which means that you're adding new listeners every time the page reloads. This will very quickly exceed a sane number of listeners on the file (and Node.js will rightly warn you about it).

Instead, create the Tail instance outside of io.on(). It should look something like this:

var filename = "output.log";
var options = { fromBeginning: true };
var tail = new Tail(filename, options);

tail.on("line", function (data) {
  console.log("triggering");
  console.log(data);
  io.sockets.emit("send-log-data-" + labName, data);
});

io.on("connection", function (socket) {
  console.log("new connection made");

  socket.on("disconnect", function () {
    console.log("disonnect request came.Disconnecting");
    socket.disconnect();
  });
});

The older answer below is not recommended any more

The problem is that you are registering a new event handler every time the page is reloaded. This causes the data to be sent multiple times. I had the same issue and I solved by using io.once() instead of io.on() in the server.

io.once('connection',function(socket){
console.log("new connection made")
...
}

This causes the connection listener to be unregistered as soon as it is called, and the data is sent only once.

Upvotes: 3

Related Questions