第二个 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
的客户端发送消息。要将消息发送给其他客户端,需要进行广播。
我正在为 '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
的客户端发送消息。要将消息发送给其他客户端,需要进行广播。