Reputation: 10261
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
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);
Upvotes: 1
Reputation: 754
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
Upvotes: 0
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
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
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
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