javascript 多次触发 Socket.io 消息事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19162582/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Socket.io message event firing multiple times
提问by amit
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.
我正在尝试学习 node 并开始使用 socket.io 创建 mashup 消息传输已经开始,但我遇到了一些麻烦。
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?
message 事件多次触发,导致一条消息在收件人的框中多次出现。我已将套接字路由到exports.chat
并想知道这是否导致了问题?
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);
}
});
});
};
采纳答案by Sriharsha
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.
socket.io 代码的整个部分必须在 external.chat 函数之外。套接字 IO 必须与 http/app 服务器绑定,您不应在每个请求中处理它。
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.
本质上发生的事情是,每次新请求到达时,您都在为消息注册一个事件处理程序,因此它被触发的次数与您访问聊天 URL 的次数一样多。
io.socket.on('message', function (data) {...})
回答by joe
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') 事件上的所有侦听器,这就是我的代码的样子 -
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.
可能不需要在断开连接时调用它,不确定但我还是这样做了。
回答by Peter Lyons
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
我认为这种不当行为是因为您试图将少数内置/保留事件名称“消息”之一用作特定于应用程序的消息。要确认,请将您的事件名称更改为“message2”或其他名称,然后查看问题是否消失。我相信至少保留了“连接”、“断开连接”和“消息”。https://github.com/LearnBoost/socket.io/wiki/Exposed-events
回答by schanzenbraut
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()