插座.IO - 同一登录用户在两个不同浏览器中使用 socket.id
SOCKET.IO - Usage of socket.id in two different browsers for same logged in user
这更像是一个关于在您想要为一个用户触发套接字事件的情况下该怎么做的问题,该套接字事件可能登录到另一个浏览器。
我有几个函数可以实时更新用户的工作区(在可由其他用户分配的其他工作区队列中);但是,如果用户同时登录到另一个浏览器,并在一个浏览器中进行更新,则它不会在另一个浏览器中更新(因为它们具有不同的 socket.id)。
我不知道该怎么办...我可以根据登录人员的用户 ID 来做到这一点,但目前我的套接字代码没有任何会话变量的范围,尽管有会话套接字等模块 - 我不确定这是否是正确的路径下降。
谁能建议我解决这个问题的方法?
如果您不使用任何集群,则可以遵循我在 Miaou 聊天中采用的方法:我只需将用户设置为套接字对象的属性,并在必要时迭代套接字。这允许一些功利功能。
下面是(简化的)相关代码。
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,我可能会实现更直接的映射,但我描述的解决方案足够健壮和高效。
相关文章:
- 当同一浏览器的两个实例浏览时,Javascript页面如何具有唯一的ID
- 在两个浏览器选项卡之间共享变量范围
- 仅在使用javascript和html的浏览器中在相同的两个选项卡之间切换
- 如何使用WebRTC在两个浏览器之间传输文件
- 不同机器上的两个浏览器查看同一页面
- 当有两个浏览器实例时,如何检查浏览器会话是否存在
- 开发两个单独的节点应用程序来提供 Web 服务和使用 Web 服务以在浏览器上呈现它是一个好主意吗?
- 我在同一域中并排打开了两个浏览器.我想将一个网格的选定行拖到另一个浏览器.可能吗
- 插座.IO - 同一登录用户在两个不同浏览器中使用 socket.id
- 谷歌浏览器在找到两个同名的变量或函数时会怎么做
- 在 JS 中,如果通过卸载调用两个函数,浏览器以什么顺序处理它们
- 是否应该在同一台计算机上的两个火狐浏览器共享相同的cookie
- 是否可以使用 JQuery 或其他方法在两个浏览器窗口之间拖放一些内容
- 两个浏览器窗口之间的通信:弹出窗口和父窗口
- 响应式设计:这个Javascript会导致浏览器下载两个图像吗?
- 检测是否对同一站点打开了两个浏览器窗口
- 当浏览器开始实现JavaScript时,如何在支持一两个版本较旧的浏览器的同时开始使用它们
- Jquery Mobile我有两个页面,一个用于Android,一个用于iPhone.如何检测浏览器并分配它们
- 将两个 socket.io 客户端连接在一起(建立套接字到套接字,跨浏览器连接)
- 如何在网页中添加两个CSS文件,一个用于Safari浏览器,一个用于iPad桌面版本