SOCKET.IO – 在两个不同的浏览器中为相同的login用户使用socket.id

这个问题更多的是关于在想要为一个用户触发一个套接字事件的情况下该怎么做,这个事件可能会被logging到另一个浏览器中。

我有几个函数实时更新用户的工作堆栈(在其他工作堆栈可由其他用户分配的队列中); 但是,如果用户同时login到另一个浏览器,并在一个浏览器中进行更新,则不会在另一个浏览器中更新(因为它们具有不同的socket.id)。

我不知道该怎么做这个…我可以根据login的人的用户ID做到这一点,但目前我的套接字代码没有任何会话variables的范围,虽然有模块,如会话-socket – 我不确定这是不是正确的道路。

任何人都可以build议我可能会接近这个方法吗?

如果你没有使用任何集群,你可以按照我在我的Miaou聊天中的方法:我只是简单地将用户设置为套接字对象的属性,并且在必要时迭代套接字。 这允许一些功利的function。

这是(简化的)相关的代码。

io.on('connect', function(socket){ ... var userId = session.passport.user; if (!userId) return die("no authenticated user in socket's session"); ... var shoe = new Shoe(socket, completeUser) // <=== bindind user socket here // socket event binding here 

鞋子对象:

 // A shoe embeds a socket and is provided to controlers and plugins. // It's kept in memory by the closures of the socket event handlers function Shoe(socket, completeUser){ this.socket = socket; this.completeUser = completeUser; this.publicUser = {id:completeUser.id, name:completeUser.name}; this.room; socket['publicUser'] = this.publicUser; this.emit = socket.emit.bind(socket); } var Shoes = Shoe.prototype; // emits something to all sockets of a given user. Returns the number of sockets Shoes.emitToAllSocketsOfUser = function(key, args, onlyOtherSockets){ var currentUserId = this.publicUser.id, nbs = 0; for (var clientId in io.sockets.connected) { var socket = io.sockets.connected[clientId]; if (onlyOtherSockets && socket === this.socket) continue; if (socket && socket.publicUser && socket.publicUser.id===currentUserId) { socket.emit(key, args); nbs++; } } return nbs; } // returns the socket of the passed user if he's in the same room Shoes.userSocket = function(userIdOrName) { var clients = io.sockets.adapter.rooms[this.room.id], sockets = []; for (var clientId in clients) { var socket = io.sockets.connected[clientId]; if (socket && socket.publicUser && (socket.publicUser.id===userIdOrName||socket.publicUser.name===userIdOrName)) { return socket; } } } // returns the ids of the rooms to which the user is currently connected Shoes.userRooms = function(){ var rooms = [], uid = this.publicUser.id; iorooms = io.sockets.adapter.rooms; for (var roomId in iorooms) { if (+roomId!=roomId) continue; var clients = io.sockets.adapter.rooms[roomId]; for (var clientId in clients) { var socket = io.sockets.connected[clientId]; if (socket && socket.publicUser && socket.publicUser.id===uid) { rooms.push(roomId); break; } } } return rooms; } // returns the first found socket of the passed user (may be in another room) function anyUserSocket(userIdOrName) { for (var clientId in io.sockets.connected) { var socket = io.sockets.connected[clientId]; if (socket.publicUser && (socket.publicUser.id===userIdOrName||socket.publicUser.name===userIdOrName)) { return socket; } } } // closes all sockets from a user in a given room exports.throwOut = function(userId, roomId, text){ var clients = io.sockets.adapter.rooms[roomId];; for (var clientId in clients) { var socket = io.sockets.connected[clientId]; if (socket.publicUser && socket.publicUser.id===userId) { if (text) socket.emit('miaou.error', text); socket.disconnect('unauthorized'); } } } 

真实的代码

现在,使用基于ES6的节点版本和WeakMap,我可能会实现更直接的映射,但是我所描述的解决scheme足够强大且高效。