11

I was trying to learn node and started creating a mashup with socket.io The message transportation have begin but I have run into some trouble.

The message event is firing multiple times leading to a single message appearing multiple times on the recipient's box. I have routed the socket to exports.chat and was wondering if that is causing the problem?

To narrow down the problem: the messages are firing the number of times = the sequence of connection of the client. That is, if a client connects second, his messages will fire twice. three times for the client connecting third.

Here is the code snippet:

exports.chat = function(io, pseudoArray, req, res){
    res.render('chat', {title: 'ChatPanel.'});

        var users = 0; 

        io.sockets.on('connection', function (socket) { // First connection
            users += 1; 
        //  reloadUsers(io, users); 

            socket.on('message', function (data) { // Broadcast the message to all
                if(pseudoSet(socket)) {
                    var transmit = {date : new Date().toISOString(), pseudo : returnPseudo(socket), message : data};
                    socket.broadcast.emit('message', transmit);
                    console.log("user "+ transmit['pseudo'] +" said \""+data+"\"");
                }
            });

            socket.set('pseudo', req.session.user, function(){
                pseudoArray.push(req.session.user);
                socket.emit('pseudoStatus', 'ok');
                console.log("user " + req.session.user + " connected");
            });

            socket.on('disconnect', function () { // Disconnection of the client
                users -= 1;
            //  reloadUsers();
                if (pseudoSet(socket)) {
                    var pseudo;
                    socket.get('pseudo', function(err, name) {
                        pseudo = name;
                    });
                    var index = pseudoArray.indexOf(pseudo);
                    pseudo.slice(index - 1, 1);
                }
            });
        });
};
amit
  • 10,133
  • 22
  • 72
  • 121

6 Answers6

7

The whole part of socket.io code has to go outside external.chat function. Socket IO has to bind with the http/app server, you should not handle it within each request.

the messages are firing the number of times = the sequence of connection of the client

What essentially happening is, each time a new request arrives you are registering a event handler for message, hence it is fired as many times as the you have accessed chat URL.

io.socket.on('message', function (data) {...})
Sriharsha
  • 2,373
  • 1
  • 16
  • 20
  • i am also facing the same problem can someone help me with this, how this problem was solved, when i changed my code to `io.sockets.on('message'` it doesn't work – Meenesh Jain Dec 07 '15 at 07:18
5

So I had the same problem. The solution is to close all your listeners on the socket.on('disconnect') event, this is what my code looks like -

 socket.on('disconnect', function () {
                socket.removeAllListeners('send message');
                socket.removeAllListeners('disconnect');
                io.removeAllListeners('connection');
            });

Might not need to call it on disconnect, not sure but I do it anyway.

joe
  • 1,563
  • 4
  • 16
  • 35
  • This doesnt actually solve the problem of when a second client logs on.. just when the one client disconnects. Still haven't fixed my problem :/ – joe May 01 '16 at 23:50
  • This was a lifesaver. Was trying to debug this for ages. Thanks! – nonbeing Dec 30 '19 at 04:50
2

I think this misbehavior is because you are attempting to use one of the handful of built-in/reserved event names "message" as an application-specific message. To confirm, change your event name to "message2" or something else and see if the problem goes away. I believe at least "connect", "disconnect", and "message" are reserved. https://github.com/LearnBoost/socket.io/wiki/Exposed-events

Peter Lyons
  • 142,938
  • 30
  • 279
  • 274
1

Link: https://socket.io/docs/v3/listening-to-events/#socketoffeventname-listener

Please use socket.off method to removes the specified listener from the listener array for the event named eventName.

socket.off("message").on("message", this.UpdateChat);

enter image description here

blackbishop
  • 30,945
  • 11
  • 55
  • 76
  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Tyler2P Dec 25 '21 at 13:20
0

Restarting the server can be responsible for several identical event listeners on the client side. If the client has not reloaded (restarted) you have to make sure that the old event listeners are deleted on the client side when establishing a new connection. You can do that with

io.socket.removeAllListeners()
0

SOCKET.IO v3.x

I don't really know why reserve event in socket.io are firing up multiple times, hence I make a logic that fits to our needs and address this problem,

I simply create a global mutable value that could change everytime the 'disconnect' fire up, here's the logic I did

let ACTIVE_USERS = []; //assume the propery of an object is { name, socket_id }
const connections = (socket) => {
  socket.on("disconnect", (reason) => {
    //lets check how many times it fires up
    console.log('YOW', reason);

    //mutate the ACTIVE_USERS 
    ACTIVE_USERS = ACTIVE_USERS .filter(user => {
      //lets figure it out if this thing helps us
      if(user.socket_id === socket.id){
        console.log('HEY!!!');

        socket.broadcast.emit('disconnected-user',[
          message: `${user.name} has been disconnected`
        })
      }
    })
  });
}

and the result of it is here

enter image description here

Marvin
  • 647
  • 7
  • 15