【问题标题】:socket.io Emit events firing multiple timessocket.io 多次触发事件
【发布时间】:2015-06-07 18:31:32
【问题描述】:

我在这里阅读了一些关于这个主题的问题,但我还不确定如何在我的情况下解决它。 getMsgs 发射事件的触发次数与我访问 /admin url 的次数一样多。我从关于 SO 的其他问题中知道这是因为每次我访问 admin 页面时听众都在注册,但我不确定如何重构我的代码(即在哪里移动 io.on(..) 以及如何调用它来自router.get('/admin'..) 函数。

router.get('/admin', function(req, res, next){
    io.on('connection', function (socket) {
        dal.findAllMessages(function(err, messages) {
            console.log('sent msgs');
            socket.emit('getMsgs', messages);
        });

        socket.on('newMsg', function(data){
            console.log('newMsg');
            console.log(data);
            dal.addMessage(data);
            dal.findAllMessages(function(err, messages) {
                socket.emit('getMsgs', messages);
            });
        });

        socket.on('delMsg', function(data){
            console.log('delMsg');
            console.log(data);
            dal.deleteMessage(data);
            dal.findAllMessages(function(err, messages) {
                socket.emit('getMsgs', messages);
            });
        });
    });
    res.render('admin');
});

【问题讨论】:

    标签: node.js socket.io


    【解决方案1】:

    io.on(...) 代码移出路线。每次/admin 路由被命中时,您都会重新注册一个新的事件处理程序,因此您会为完全相同的事件获得多个事件处理程序。

    router.get('/admin', function(req, res, next){
        res.render('admin');
    });
    
    io.on('connection', function (socket) {
        dal.findAllMessages(function(err, messages) {
            console.log('sent msgs');
            socket.emit('getMsgs', messages);
        });
    
        socket.on('newMsg', function(data){
            console.log('newMsg');
            console.log(data);
            dal.addMessage(data);
            dal.findAllMessages(function(err, messages) {
                socket.emit('getMsgs', messages);
            });
        });
    
        socket.on('delMsg', function(data){
            console.log('delMsg');
            console.log(data);
            dal.deleteMessage(data);
            dal.findAllMessages(function(err, messages) {
                socket.emit('getMsgs', messages);
            });
        });
    });
    

    如果您不希望在遇到/admin 路由之前安装 socket.io 事件处理程序,那么您可以保留一个标志以表明它们是否已设置。

    如果您只希望 socket.io 事件处理程序应用于特定的管理客户端,那么您将需要一种不同的方法,使用某种身份验证来决定是否允许 socket.io 连接连接。

    【讨论】:

    • 如果您需要访问req,有什么合适的方法来处理这个问题?
    • @mumush - req 仅在给定请求期间存在,因此它通常不适用于 socket.io 事件期间。换句话说,没有特定的 http request 对象对应于传入的 socket.io 事件。因此,必须更详细地描述您的问题,以了解您真正想要做什么/解决什么。我建议您创建自己的问题并在那里描述您的实际情况。
    【解决方案2】:

    尝试使用socket.removeAllListeners()

    【讨论】:

      猜你喜欢
      • 2013-10-10
      • 1970-01-01
      • 2023-03-26
      • 2013-06-08
      • 2021-12-31
      • 2019-10-30
      • 2021-01-13
      • 1970-01-01
      • 2015-11-22
      相关资源
      最近更新 更多