Socket.io - io.to.emit 发送给所有连接的用户

Socket.io - io.to.emit emits to all connected users

我在客户端上使用 npm socket.io 和 expressjs 和 btford.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) 是否有更好的方法来避免为每个用户使用独特的房间?这不是聊天应用程序,而是实现推送通知

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

假设您项目的 socket.io 部分与应用程序 web/express 部分中的 http 请求完全分开。这就是您应该如何考虑传递消息。

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

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

在这段代码中:

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 对该用户来说是完全唯一的,并且所需的用户已经通过该名称加入了聊天室。这可能行得通,但这取决于那些具体的事情是否正确。