来自Meteor world &我很好奇如何复制缓存的pubsub/观察者功能。举一个基本的例子,假设我有一个todolist,其中每个todo都有一个userId,我想让每个userId都有一个todo私有(但一个userId可以存在于多个连接的设备上,例如电话+桌面)。我想我必须创建一些发布函数,通过发送的请求中的socketId验证userId,然后创建一个特定于该查询的套接字名称空间(因为该查询可能包含不止一个userId约束)。然后,注册一个发射器,该发射器只将更改发送到那些被验证为侦听给定名称空间的socketId。我说得对吗?我的所有研究都只是返回一些基本的东西,比如根据关键字发布给所有连接的用户。任何到阅读材料的链接都会很棒!这是第一次尝试注释中缺少的逻辑...
export function sendTodosByUserId(io, userId) {
//How to auth? By linking a client socketId to a user in a lookup table?
connect()
.then(conn => {
r
.table('todos')
.filter(todos => todos("userId").eq(userId))
.changes().run(conn, (err, cursor) => {
cursor.each((err, change) => {
//Do I emit a unique message? namespace? How do I handle 2 clients using the same userId?
io.emit('TODO_CHANGE', change);
});
});
});
}发布于 2015-11-23 02:18:35
您可以实现某种方式将新套接字映射到正确的用户。例如,您可以将userId放在Express session中,并将用户的套接字ids存储在一个简单的对象中。
var userSockets = {};
io.sockets.on('connection', function(socket) {
var userId = socket.handshake.session.userId;
if(userSockets[userId]) {
userSockets[userId].push(socket.id);
} else {
userSockets[userId] = [socket.id];
sendTodosByUserId(io, userId)
}
socket.on('disconnect', function() {
var i = userSockets[userId].indexOf(socket.id);
userSockets[userId].splice(i);
if(userSockets[userId].length === 0) {
delete userSockets[userId];
}
});
});在您的sendTodosByUsedId中,您只需循环遍历属于用户的套接字数组,并向每个套接字发出。
var sockets = userSockets[userId];
for(var i = 0; i < sockets.length; ++i) {
io.to(sockets[i]).emit('TODO_CHANGE', change);
}请注意,如果您有多个节点可以连接到用户,这将不会工作。然后,您可能必须将userSockets-object存储在例如Redis中。
或者,你可以让你的用户加入一个名为user:<userId>的房间,并在每次todo-change时发送到这个房间。
io.sockets.on('connection', function(socket) {
var userId = socket.handshake.session.userId;
socket.join('user:' + userId);
socket.on('disconnect', function() {
console.log("Rooms are left automatically on disconnect");
}
});在待办事项更改时:
io.to('user:' + userId).emit('TODO_CHANGE', change);https://stackoverflow.com/questions/33663565
复制相似问题