维护与同一用户打开的每个新选项卡的套接字 io 连接
Maintain socketio conection to each new tab opened by the same user
我正在为我们的网站制作一个应用程序,用户可以在该网站上相互发送聊天消息。我已经成功地使用 nodejs 和 socketio 做到了这一点。我有一个 header,带有某种通知图标,就像在所有页面中都可以看到的 facebook 一样。现在,如果用户打开多个选项卡并收到一条消息,那么所有打开的选项卡都应该看到图标亮起。我通过跟踪用户通过 2D 套接字数组打开的套接字连接来实现这一点:
var container = {};
io.sockets.on( 'connection', function(client) {
client.on('set account online', function(username) {
if (!(username in container)) {
console.log(username + " is now Online" );
container[username] = [];
}
client.username = username;
container[username].push(client);
});
client.on('set account offline', function(username) {
if (username in container) {
delete container[username];
console.log(username + " is now Offline" );
}
});
然后当发送消息时,我遍历适当的数组元素
client.on('send message', function(data) {
if (data.recipient in container) {
var clients = container[data.recipient];
for(var i = 0; i < clients.length;i++){
clients[i].emit('send message', {recipient: data.recipient, message: data.message });
}
}
});
这一切都很好(虽然不确定它的编码有多好)。问题是,如果用户关闭了一个选项卡,该选项卡的套接字仍然存在于 container
变量中,并且如果收到该特定用户的消息,节点仍会尝试发送到该套接字。此外,un-track 任何断开连接的套接字感觉更干净。
我一直在考虑这个问题,我想我必须将套接字断开连接事件与客户端的 onbeforeunload
事件联系起来,我们都知道它在不同浏览器中的表现。关于从 container
数组拼接断开连接的套接字的正确方法是什么有什么建议吗?
根据我的评论:
You should really be implementing rooms. On each connection each user
should join their own room, any additional connections from the same
user should join this room. You can then emit data to the room and
each client inside it will receive the data.
您的代码可以更改为:
io.sockets.on('connection', function(client) {
client.on('set account online', function(username) {
client.join(username);
});
client.on('set account offline', function(username) {
client.leave(username);
});
client.on('send message', function(data) {
io.to(data.recipient).emit('send message', {
recipient: data.recipient,
message: data.message
});
});
});
我正在为我们的网站制作一个应用程序,用户可以在该网站上相互发送聊天消息。我已经成功地使用 nodejs 和 socketio 做到了这一点。我有一个 header,带有某种通知图标,就像在所有页面中都可以看到的 facebook 一样。现在,如果用户打开多个选项卡并收到一条消息,那么所有打开的选项卡都应该看到图标亮起。我通过跟踪用户通过 2D 套接字数组打开的套接字连接来实现这一点:
var container = {};
io.sockets.on( 'connection', function(client) {
client.on('set account online', function(username) {
if (!(username in container)) {
console.log(username + " is now Online" );
container[username] = [];
}
client.username = username;
container[username].push(client);
});
client.on('set account offline', function(username) {
if (username in container) {
delete container[username];
console.log(username + " is now Offline" );
}
});
然后当发送消息时,我遍历适当的数组元素
client.on('send message', function(data) {
if (data.recipient in container) {
var clients = container[data.recipient];
for(var i = 0; i < clients.length;i++){
clients[i].emit('send message', {recipient: data.recipient, message: data.message });
}
}
});
这一切都很好(虽然不确定它的编码有多好)。问题是,如果用户关闭了一个选项卡,该选项卡的套接字仍然存在于 container
变量中,并且如果收到该特定用户的消息,节点仍会尝试发送到该套接字。此外,un-track 任何断开连接的套接字感觉更干净。
我一直在考虑这个问题,我想我必须将套接字断开连接事件与客户端的 onbeforeunload
事件联系起来,我们都知道它在不同浏览器中的表现。关于从 container
数组拼接断开连接的套接字的正确方法是什么有什么建议吗?
根据我的评论:
You should really be implementing rooms. On each connection each user should join their own room, any additional connections from the same user should join this room. You can then emit data to the room and each client inside it will receive the data.
您的代码可以更改为:
io.sockets.on('connection', function(client) {
client.on('set account online', function(username) {
client.join(username);
});
client.on('set account offline', function(username) {
client.leave(username);
});
client.on('send message', function(data) {
io.to(data.recipient).emit('send message', {
recipient: data.recipient,
message: data.message
});
});
});