Socket.IO - 如何为不同的 endpoints/rooms 获取不同的活跃用户列表?
Socket.IO - how to get different active user lists for different endpoints/rooms?
我正在写一个简单的基于socket.io(v1.3.6)的聊天程序。当用户使用他们的用户名登录时,他们可以在仪表板中看到几个聊天室,并通过不同的端点进入每个聊天室,即
http://localhost:8080/api/chats/room01
.
用户可以在这些房间中的任何一个聊天。我想为每个房间创建一个活跃用户列表。 'active' 表示此用户现在已连接到套接字(在这个房间聊天)。
我看到很多问题已经发布,但仍然被他们几个孤立的词弄糊涂了。
在我当前的 server.js 中,我添加了这段代码:
var io = require('socket.io')(http);
io.on('connection', function(socket){
console.log('a user connected: ' + socket.id);
socket.on('disconnect', function(){
console.log(socket.id + ' has disconnected from the chat.');
});
});
总结一下,两个问题:
如何区分不同rooms/endpoints的套接字连接?
如何获得活动用户名而不是 socket.id
,对于同一用户可能不同?
非常感谢。
更新:
我的服务器端代码:
io.of('/rooms/room01').on('connection', function(socket) {
console.log("socket connected: ", socket.id);
//....some more codes
});
我的客户端代码:
app.factory('socketio', ['$rootScope', function($rootScope) {
'use strict';
var socket = io.connect('http://localhost:8080/rooms/room01');
return {
on: function(eventName, callback) {
socket.on(eventName, function() {
var args = arguments;
$rootScope.$apply(function() {
callback.apply(socket, args);
});
});
},
emit: function(eventName, data, callback) {
socket.emit(eventName, data, function() {
var args = arguments;
$rootScope.$apply(function() {
if (callback) {
callback.apply(socket, args);
}
});
});
}
};
}]);
以上代码无效。但是以前当我使用默认命名空间时
io.of('/').on('connection', function(socket) {
//...
}
和
var socket = io.connect('http://localhost:8080/');
效果很好。你能告诉我为什么吗?
How can I distinguish the socket connections for different
rooms/endpoints?
在您的服务器上,有几种方法可以列出各个房间和每个房间的插座。以下是有关您可以在服务器上访问的各种数据的一些信息,然后您可以决定哪种方式是获取您想要的内容的最有效方式:
io.sockets.adapter.rooms
这是一个包含所有房间作为键的对象,这些房间目前至少有一个连接。这包含您的服务器称为 .join()
的两个房间,用于手动将套接字加入房间,并包含每个套接字自动加入的每个默认房间(具有 socket.id 的名称)。所以,如果你知道你有一个名为 "test"
的房间,那么你可以用 io.sockets.adapter.rooms['test']
.
获得一个对象,每个房间作为键
io.sockets.connected
这是一个包含当前连接的每个套接字的对象,其中 socket.id 是对象中的键。因此,如果 id 是 vlPYz3EHUOe8vFitAAAJ
,那么您可以访问该 id 的套接字对象作为 io.sockets.connected['vlPYz3EHUOe8vFitAAAJ']
。您显然可以使用 for (var sock in io.sockets.connected)
类型的循环来迭代所有连接的套接字。然后,在该套接字对象内部,您可以通过以下方式查看它所在的房间:io.sockets.connected['vlPYz3EHUOe8vFitAAAJ'].rooms
这是它所在的房间名称数组。此房间名称数组将包括与 socket.id
.
io.sockets.sockets
这是一组已连接的套接字,与使用 io.sockets.connected
相比,访问所有当前已连接的套接字可能是一种更简单的方法。就像上一节中描述的那样,一旦你有一个给定的连接插座,你就可以访问 socket.rooms
属性 来获取插座当前所在的房间数组。
对于特定的插座,您可以通过以下方式获取它所在的房间列表:
socket.rooms
这是给定插座当前所在的房间名称的数组。这包括与 socket.id
同名的自动房间名称,因此如果只是尝试,您可能想忽略该房间名称列出插座所在的常规房间。
How can I get active usenames instead of socket.id which could be
different for the same user?
由于用户名是您指定的,与 socket.io 没有任何关系,因此您必须自己找到一种方法将用户名与套接字相关联。根据已知用户名的位置,您可以在不同的地方执行此操作。如果它已经存在于 cookie 中,那么您可以从以下位置获取它:socket.handshake.headers.cookie
这是在最初连接套接字时为该特定套接字设置的 cookie 的快照。
如果在最初连接套接字时通过其他方式知道用户名,您可以从其他机制获取它并将其保存为套接字对象的 属性:socket.username = 'xxx';
然后你就可以随时从服务器端套接字对象访问它了。
这是我用来探索这些不同数据结构的一些服务器端诊断代码:
'use strict';
var express = require('express');
var app = express();
var server = app.listen(80);
var io = require('socket.io')(server);
app.use(express.static('public'));
io.on('connection', function(socket) {
console.log("socket connected: ", socket.id);
// list all connected sockets
var list = io.sockets.sockets;
console.log("Connected sockets:");
list.forEach(function(s) {
console.log(" socket.id = ", s.id);
});
socket.on('join', function(name) {
socket.join(name);
// list all rooms
console.log("Active rooms:");
var rooms = io.sockets.adapter.rooms;
for (var room in rooms) {
if (rooms.hasOwnProperty(room)) {
console.log(" ", room);
}
}
// list all rooms this socket is in:
console.log("Active rooms for this socket:");
io.sockets.connected[socket.id].rooms.forEach(function(room) {
console.log(" ", room);
});
});
socket.on('leave', function(name) {
socket.leave(name);
});
});
我正在写一个简单的基于socket.io(v1.3.6)的聊天程序。当用户使用他们的用户名登录时,他们可以在仪表板中看到几个聊天室,并通过不同的端点进入每个聊天室,即
http://localhost:8080/api/chats/room01
.
用户可以在这些房间中的任何一个聊天。我想为每个房间创建一个活跃用户列表。 'active' 表示此用户现在已连接到套接字(在这个房间聊天)。
我看到很多问题已经发布,但仍然被他们几个孤立的词弄糊涂了。
在我当前的 server.js 中,我添加了这段代码:
var io = require('socket.io')(http);
io.on('connection', function(socket){
console.log('a user connected: ' + socket.id);
socket.on('disconnect', function(){
console.log(socket.id + ' has disconnected from the chat.');
});
});
总结一下,两个问题:
如何区分不同rooms/endpoints的套接字连接?
如何获得活动用户名而不是
socket.id
,对于同一用户可能不同?
非常感谢。
更新:
我的服务器端代码:
io.of('/rooms/room01').on('connection', function(socket) {
console.log("socket connected: ", socket.id);
//....some more codes
});
我的客户端代码:
app.factory('socketio', ['$rootScope', function($rootScope) {
'use strict';
var socket = io.connect('http://localhost:8080/rooms/room01');
return {
on: function(eventName, callback) {
socket.on(eventName, function() {
var args = arguments;
$rootScope.$apply(function() {
callback.apply(socket, args);
});
});
},
emit: function(eventName, data, callback) {
socket.emit(eventName, data, function() {
var args = arguments;
$rootScope.$apply(function() {
if (callback) {
callback.apply(socket, args);
}
});
});
}
};
}]);
以上代码无效。但是以前当我使用默认命名空间时
io.of('/').on('connection', function(socket) {
//...
}
和
var socket = io.connect('http://localhost:8080/');
效果很好。你能告诉我为什么吗?
How can I distinguish the socket connections for different rooms/endpoints?
在您的服务器上,有几种方法可以列出各个房间和每个房间的插座。以下是有关您可以在服务器上访问的各种数据的一些信息,然后您可以决定哪种方式是获取您想要的内容的最有效方式:
io.sockets.adapter.rooms
这是一个包含所有房间作为键的对象,这些房间目前至少有一个连接。这包含您的服务器称为 .join()
的两个房间,用于手动将套接字加入房间,并包含每个套接字自动加入的每个默认房间(具有 socket.id 的名称)。所以,如果你知道你有一个名为 "test"
的房间,那么你可以用 io.sockets.adapter.rooms['test']
.
io.sockets.connected
这是一个包含当前连接的每个套接字的对象,其中 socket.id 是对象中的键。因此,如果 id 是 vlPYz3EHUOe8vFitAAAJ
,那么您可以访问该 id 的套接字对象作为 io.sockets.connected['vlPYz3EHUOe8vFitAAAJ']
。您显然可以使用 for (var sock in io.sockets.connected)
类型的循环来迭代所有连接的套接字。然后,在该套接字对象内部,您可以通过以下方式查看它所在的房间:io.sockets.connected['vlPYz3EHUOe8vFitAAAJ'].rooms
这是它所在的房间名称数组。此房间名称数组将包括与 socket.id
.
io.sockets.sockets
这是一组已连接的套接字,与使用 io.sockets.connected
相比,访问所有当前已连接的套接字可能是一种更简单的方法。就像上一节中描述的那样,一旦你有一个给定的连接插座,你就可以访问 socket.rooms
属性 来获取插座当前所在的房间数组。
对于特定的插座,您可以通过以下方式获取它所在的房间列表:
socket.rooms
这是给定插座当前所在的房间名称的数组。这包括与 socket.id
同名的自动房间名称,因此如果只是尝试,您可能想忽略该房间名称列出插座所在的常规房间。
How can I get active usenames instead of socket.id which could be different for the same user?
由于用户名是您指定的,与 socket.io 没有任何关系,因此您必须自己找到一种方法将用户名与套接字相关联。根据已知用户名的位置,您可以在不同的地方执行此操作。如果它已经存在于 cookie 中,那么您可以从以下位置获取它:socket.handshake.headers.cookie
这是在最初连接套接字时为该特定套接字设置的 cookie 的快照。
如果在最初连接套接字时通过其他方式知道用户名,您可以从其他机制获取它并将其保存为套接字对象的 属性:socket.username = 'xxx';
然后你就可以随时从服务器端套接字对象访问它了。
这是我用来探索这些不同数据结构的一些服务器端诊断代码:
'use strict';
var express = require('express');
var app = express();
var server = app.listen(80);
var io = require('socket.io')(server);
app.use(express.static('public'));
io.on('connection', function(socket) {
console.log("socket connected: ", socket.id);
// list all connected sockets
var list = io.sockets.sockets;
console.log("Connected sockets:");
list.forEach(function(s) {
console.log(" socket.id = ", s.id);
});
socket.on('join', function(name) {
socket.join(name);
// list all rooms
console.log("Active rooms:");
var rooms = io.sockets.adapter.rooms;
for (var room in rooms) {
if (rooms.hasOwnProperty(room)) {
console.log(" ", room);
}
}
// list all rooms this socket is in:
console.log("Active rooms for this socket:");
io.sockets.connected[socket.id].rooms.forEach(function(room) {
console.log(" ", room);
});
});
socket.on('leave', function(name) {
socket.leave(name);
});
});