amit
amit

Reputation: 10261

Socket.io message event firing multiple times

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);
                }
            });
        });
};

Upvotes: 10

Views: 25972

Answers (6)

vinoth kumar
vinoth kumar

Reputation: 11

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

Upvotes: 1

Marvin
Marvin

Reputation: 754

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

Upvotes: 0

schanzenbraut
schanzenbraut

Reputation: 21

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()

Upvotes: 0

joe
joe

Reputation: 1713

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.

Upvotes: 6

Sriharsha
Sriharsha

Reputation: 2443

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) {...})

Upvotes: 7

Peter Lyons
Peter Lyons

Reputation: 145994

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

Upvotes: 2

Related Questions