node.js - socket.io 发出多次触发的事件

标签 node.js socket.io

我在这里阅读了一些关于这个主题的问题,但我还不确定如何解决我的问题。 getMsgs emit 事件触发的次数与我访问 /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');
});

最佳答案

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 连接。

关于node.js - socket.io 发出多次触发的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30697036/

相关文章:

node.js - 使用 PassportJS 时将用户序列化/反序列化到 session 中的目的是什么?

mysql - 使用 JWT 对 Web 和移动客户端进行 API 身份验证

javascript - Socket.io 和 PHP 集成

javascript - Socket.io emit() 延迟/缓冲区刷新?

node.js - 如何使用docker将应用程序发布到heroku?

javascript - 使用 Node.js 请求抓取网站并获取奇怪的字符

node.js - 堆外 Node.js 中的内存泄漏?

javascript - 类型错误 : Request path contains unescaped characters

php - 在 Windows 上使用 less 和 symfony2

node.js - 在快速 route 使用 socket.io