第二个 socket.io 在服务器端发出未被 angular 接收

Second socket.io emit on server side not being received by angular

我正在为 'match' 用户实时使用 socket.io 构建应用程序。这个想法是 user a 按下要匹配的按钮,然后当 user b 发出匹配请求时,通过向两个客户端发送 io 消息来匹配两者。我正在使用 AngularJS 和 ui-router and bt-fords socket.io.

客户端在输入controller时发出请求如下图:

lunchrControllers.controller('UserMatchingController', ['$state', 'socket', 'authService',
    function ($state, socket, authService) {
        socket.emit('match', {userEmail: authService.currentUser()});

        var currEmail = authService.currentUser();
        // only want to catch emits suffixed with the users email
        socket.on('matched' + currEmail, function (data) {
            $state.go('users.matched', {name: data.name})
        });
    }]);

其中 authService 用于保存当前登录用户的电子邮件。在服务器端,我有一些代码可以与 mongoose 一起使用数据库(它绝对可以被清理),如下所示:

var mongoose = require('mongoose');
var User = mongoose.model('User');

module.exports = function(socket) {

    socket.on('match', function(data){

        User.findOne({email: data.userEmail}, function(error, user) {
            if(error){
                return
            }

            user.wantsToBeMatched = true;
            user.save(function(err){
                // bleh
            });
        });

        User.find({email: {'$ne': data.userEmail }, wantsToBeMatched: true}, function(error, users){
            if(error || users.length == 0){
                //bleh
                return
            }
            console.log(users);

            User.findOne({email: data.userEmail}, function(error, currentUser) {
                if(error) {
                    return;
                }

                // there is another user who wants to be matched
                users[0].wantsToBeMatched = false;
                users[0].matchedWith = currentUser.firstname;
                currentUser.wantsToBeMatched = false;
                currentUser.matchedWith = users[0].firstname;

                users[0].save(function() {});
                currentUser.save(function() {});

                console.log("I'm gonna emit " + ('matched' + currentUser.email) + " with name = " + currentUser.matchedWith);
                console.log("I'm gonna emit " + ('matched' + users[0].email) + ' with name = ' + users[0].matchedWith);

                socket.emit('matched' + users[0].email, {name: users[0].matchedWith});
                socket.emit('matched' + currentUser.email, {name: currentUser.matchedWith});
            });
        });
    })
};

问题是只有第二个用户(在本例中为 user b)请求匹配从服务器收到 socket.emit。我试过更改服务器中发出消息的顺序,但没有帮助。控制台日志记录正是我所期望的:

I'm gonna emit matcheda@a.com with name = b
I'm gonna emit matchedb@b.com with name = a

我试过使用不同的浏览器,使用隐身模式,将代码放在 EC2 实例上,让朋友在不同的 IP 上尝试,每次都得到相同的结果。 基本上,问题归结为以下代码未在 user a 的浏览器中执行:

socket.on('matched' + currEmail, function (data) {
    $state.go('users.matched', {name: data.name})
});

想通了。这是我需要进行的更改:

socket.broadcast.emit('matched' + users[0].email, {name: users[0].matchedWith});

我漏了 broadcast 这个词。我以前的代码不起作用的原因是(根据我对 socket.io 的新理解)socket.emit 只向触发 socket.on 的客户端发送消息。要将消息发送给其他客户端,需要进行广播。