Socket.io消息事件多次触发

时间:2013-10-03 15:01:48

标签: javascript node.js socket.io

我正在尝试学习节点并开始使用socket.io创建一个mashup 消息传输已经开始,但我遇到了一些麻烦。

消息事件多次触发,导致单个消息在收件人的框中多次出现。我已经将套接字路由到exports.chat并且想知道这是否导致问题?

缩小问题的范围:消息的触发次数=客户端的连接顺序。也就是说,如果客户端连接第二个,他的消息将触发两次。连接第三个的客户三次。

以下是代码段:

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

4 个答案:

答案 0 :(得分:5)

socket.io代码的整个部分必须在external.chat函数之外。套接字IO必须与http / app服务器绑定,您不应在每个请求中处理它。

  

消息的触发次数=客户端的连接顺序

实质上发生的是,每次新请求到达时,您都在为消息注册一个事件处理程序,因此它会被触发聊天URL的次数。

io.socket.on('message', function (data) {...})

答案 1 :(得分:3)

所以我遇到了同样的问题。解决方案是在socket.on('disconnect')事件中关闭所有侦听器,这就是我的代码 -

<form id="testform"> rest of the code goes here </form>

可能不需要在断开连接时调用它,不确定,但无论如何我都这样做。

答案 2 :(得分:1)

我认为这种不当行为是因为您试图将少数内置/保留事件名称“message”中的一个用作特定于应用程序的消息。要确认,请将您的活动名称更改为“message2”或其他内容,然后查看问题是否消失。我相信至少“连接”,“断开连接”和“消息”是保留的。 https://github.com/LearnBoost/socket.io/wiki/Exposed-events

答案 3 :(得分:0)

重新启动服务器可以负责客户端上的几个相同的事件侦听器。如果客户端尚未重新加载(重新启动),则必须确保在建立新连接时在客户端删除旧的事件侦听器。您可以使用

io.socket.removeAllListeners()