socket.on event gets triggered multiple times socket.on event gets triggered multiple times express express

socket.on event gets triggered multiple times


The problem is caused by your client code. Each time you call the reply() function in the client you set up an additional socket.on('Ans', ...) event handler which means they accumulate. You can change that to socket.once() and it will remove itself each time after it get the Ans message. You can then also remove your flag variable.

function reply() {  socket.emit('Quest' , Quest);  audio.play();  // change this to .once()  socket.once('Ans', function(replyFromBot) {    console.log("hi");    var para = document.createElement("p2");    x = document.getElementById("MiddleBox");    para.appendChild(document.createTextNode(replyFromBot));    x.appendChild(para);    x.scrollTop = x.scrollHeight;  });}

Socket.io is not really built as a request/response system which is what you are trying to use it as. An even better way to implement this would be to use the ack capability that socket.io has so you can get a direct response back to your Quest message you send.

You also need to fix your shared variables replyFromBot and listen on your server because those are concurrency problems waiting to happen as soon as you have multiple users using your server.


Better Solution

A better solution would be to use the ack capability that socket.io has to get a direct response to a message you sent. To do that, you'd change your server to this:

function newConnection(socket) {    console.log(socket.id);    socket.on('Quest', function(data, fn) {      let replyFromBot = bot.reply("local-user", data);      console.log(socket.id+ " "+replyFromBot);      // send ack response      fn(replyFromBot);    });}

And, change your client code to this:

function reply() {    audio.play();    socket.emit('Quest', Quest, function(replyFromBot) {        console.log("hi");        var para = document.createElement("p2");        x = document.getElementById("MiddleBox");        para.appendChild(document.createTextNode(replyFromBot));        x.appendChild(para);        x.scrollTop = x.scrollHeight;    });}

Doing it this way, you're hooking into a direct reply from the message so it works as request/response much better than the way you were doing it.


Instead of socket.on('Quest' ,reply); try socket.once('Quest' ,reply);

The bug in your code is that each time newConnection() is called node registers a event listener 'Quest'. So first time newConnection() is called the number of event listener with event 'Quest' is one, the second time function is called, number of event listener increases to two and so on

socket.once() ensures that number of event listener bound to socket with event 'Quest' registered is exactly one