【问题标题】:Socket.io - io.to.emit emits to all connected usersSocket.io - io.to.emit 向所有连接的用户发出
【发布时间】:2015-02-25 09:14:17
【问题描述】:

我在客户端上有一个带有 expressjs 和 btford.socket-io 的 npm socket.io 的 MEAN 应用程序设置。

angular.module('myApp',['btford.socket-io'])
    .factory('socket',function(socketFactory){
       return socketFactory();
    }
).controller('myAppCtrl',['$scope','socket',
    function(a,b){
            b.on('test',function(data){
            console.log(data);
        });
    } 
]);

这是 node-express 设置:

var app = express(),
    server = app.listen(3000);

var socket = require('socket.io'),
    io = socket.listen(server);

require('/config/routes/index.js')(app,io);
require('/config/routes/test.js')(app,io);

路由:(config/routes/index.js)

module.exports = function(app,io){
    app.get('/',function(req,res){
        io.on('connection',function(socket){
            socket.join(req.session._id);
        });
        res.render('index');
    });
};

config/routes/test.js

module.exports = function(app,io){
    app.get('/route1',function(req,res){
        io.to(req.session._id).emit('test',{
            data : 'Works'
        });
        res.render('route1');
    });  
};

A) 每当用户转到 route1 时,就会触发 emit 事件并将其发送给所有用户。

B) 有没有更好的方法来避免为每个用户使用不同的房间?这不是聊天应用程序,而是实现推送通知

【问题讨论】:

    标签: javascript angularjs node.js sockets socket.io


    【解决方案1】:

    您对套接字和请求的工作方式有几个主要误解。它们是非常独立的操作,并不像您想象的那样相互关联。我将尝试解释您的代码存在的问题。

    在这段代码中:

    module.exports = function(app,io){
        app.get('/',function(req,res){
            io.on('connection',function(socket){
                socket.join(req.session._id);
            });
            res.render('index');
        });
    };
    

    您正在处理 / 页面请求,并且每次该请求被命中时,您都会为 io.on('connection', ...) 添加另一个事件处理程序,因此您可以拥有许多这样的事件处理程序。

    此外,如果连接事件发生在用户点击/ 页面之前,那么您将完全错过它,并且该套接字将不会被放置到正确的聊天室中。


    那么,在这段代码中:

    module.exports = function(app,io){
        app.get('/route1',function(req,res){
            io.to(req.session._id).emit('test',{
                data : 'Works'
            });
            res.render('route1');
        });  
    };
    

    io.to() 接受一个字符串,它是聊天室的名称。因此,这将向req.session._id 聊天室中的每个套接字发送一条消息。为此,您必须绝对确保 req.session._id 对该用户来说是完全唯一的,并且所需的用户已经以该名称加入了聊天室。这可能有效,但这取决于那些具体的事情是否正确。

    【讨论】:

    • 哇!我想我完全误解了这一点。与多个路由文件一起使用时,文档/示例有限。我尝试将 io.connection 移动到 app.js 文件,但我无法获得套接字引用?有没有办法获取 io 连接的套接字引用并将其传递给其他文件以确保它是唯一的,或者我该如何处理?我尝试使用 req.user._id 代替 sessionID,但即使这样也会发送给所有用户
    【解决方案2】:

    您需要将来自 socket.io 的连接与请求分开考虑。它们以您认为的方式捆绑在一起。您的连接侦听器适用于任何连接,而不仅仅是与给定请求相关的连接......您尝试做的事情根本不会那样工作。

    想象一下,您项目的 socket.io 部分与应用程序的 web/express 部分中的 http 请求完全分开。这就是您应该如何看待传递消息的方式。

    另外值得考虑的是,如果您使用集群或类似的扩展方法,您在一个实例中的默认 socket.io 设置不会与其他实例通信。

    【讨论】:

      猜你喜欢
      • 2019-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-13
      相关资源
      最近更新 更多