Socket.io Client repeats event action multiple times from one emit

I am creating a simple diffie hellman demo with sockets and it seems that whenever my server emits any event, the client repeats it multiple times.

For example: On the client side whenever I add a message I emit this new message to the server like so.

  const addMessage = (text) => {
    var newMessage = {
      id: nextID,
      from: name,
      message: text
    }
    socket.emit("send-message", newMessage);
    setNextID(nextID + 1);    
    setMessages([...messages, newMessage]);
  }

And then on the server side I add that message to the messages and emit the new bank of messages to the other clients.

    // Send message to other person
    socket.on("send-message", (message) => {    
        messages = [...messages, message];
        console.log(messages, "Newlinen");
        
        socket.broadcast.emit("receive-message", messages);
    })

The clients receive it and updates their message bank. I console.log these actions.

    socket.on("receive-message", (receivedMessages) => {
      console.log("receieved messages");
      setMessages(receivedMessages);
    });

But when I send a message it console.logs it repeats it like 100 times??
Socket.io Client repeats event action multiple times from one emit

This happens for a lot of my other client side events handlers, repeating a action more than once, from just one emit from the server.

Why does this happen and how can I stop it?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

If you are using ReactJs, be aware that if you add the listener in your components, any time the component gets updated it will add a new socket listener and for example on second second render, you’ll get 2 console.log s. So you must add the listener in your useEffect hook (componentDidMount in class component case).

And consider that even your components can be viewed a few times so then the listener will be duplicated. So you have to close your listeners on useEffect‘s return (componentWillUnmount in class component case)

So it must be like:

useEffect(() => {
    socket.on("receive-message", (receivedMessages) => {
      console.log("receieved messages");
      setMessages(receivedMessages);
    });

    return () => {
      socket.off("receive-message");
    };
}, []);

Method 2

try to change like:

client-side:

socket.emit(“your event name”, “msg”)

server-side:

var io = new require(“socket-io”)()
io.on(“connection”, (socket) => {
    socket.on(“your event name”, (msg) => {
        io.emit(“your event name”, msg)
    })
})

try it out and it will be better 😀

Method 3

Just send the new message

Client

socket.on("receive-message", (receivedMessages) => {
  console.log("receieved messages");
  setMessages(prevMessage => [...prevMessage, receivedMessages]);
});

Server

socket.on("send-message", message => {    
    messages = [...messages, message];
    console.log(messages, "Newlinen");
        
    socket.broadcast.emit("receive-message", message);
})


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x