环境
socket.io 2.1.1
express 4.16.3
Node v10.13.0
期望的行为
当客户加入房间时,房间中的所有客户都会收到房间中所有客户的列表,包括每个客户的自定义socket.username
属性。
我尝试过的事情
尝试01:
将clients()
方法与回调一起使用,请参见:
https://socket.io/docs/server-api/#namespace-clients-callback。
socket.on('join', function(data) {
// get desired room name
var room = data.room;
// get username
var username = data.username;
// add username key:value to socket
socket.username = username;
// add socket to room
socket.join(room);
// get list of clients in room
io.of('/').in(room).clients((error, clients) => {
if (error) {
throw error;
} else {
// send data to all clients in room
io.in(room).emit('room_join', { username: socket.username, room: room, clients: clients });
}
});
});
在上面的示例中,clients
作为套接字ID的数组返回。
尝试02:
使用受this answer启发的io.sockets.adapter.rooms[room]
:
socket.on('join', function(data) {
var room = data.room;
var username = data.username;
socket.username = username;
socket.join(room);
var sockets_in_room = io.sockets.adapter.rooms[room];
io.in(room).emit('room_join', { username: socket.username, room: room, sockets_in_room: sockets_in_room });
});
以上返回:
Room { sockets: { '3-fHYqg7e8h-6K8EAAAC': true }, length: 1 }
问题
似乎可以通过以下方式将自定义username
属性添加到套接字:
socket.username= "john";
如何在“客户端对象”列表中访问该属性,以便可以访问房间中所有客户端的用户名?
编辑1
在相关的情况下,在这种情况下可能有数千个房间,每个房间名称都来自唯一的内容ID,因此任何解决方案都需要适应该约束。
编辑2
我进行了以下操作,但似乎可行,不确定是否朝正确的方向前进
var users_in_rooms = {};
io.on('connection', function(socket) {
// handle joining
socket.on('join', function(data) {
var room = data.room;
var username = data.username;
socket.username = username;
socket.join(room);
// add key:value to users_in_rooms object
users_in_rooms[socket.id] = username;
// get list of clients in room
io.of('/').in(room).clients((error, clients) => {
if (error) {
throw error;
} else {
// for each socket id in the clients array, look up its corresponding username
var client_object_array = clients.map(socketid => ({
socketid: socketid,
username: users_in_rooms[socketid]
}));
// return client_object_array to all clients
io.in(room).emit('room_join', { client_object_array: client_object_array, username: socket.username, room: room });
}
});
});
// handle leaving
socket.on('leave_all', function() {
socket.leaveAll();
// when a user leaves all rooms, delete their corresponding entry from the users_in_rooms object
delete users_in_rooms[socket.id];
});
// handle disconnecting
socket.on('disconnect', function(reason) {
console.log("client " + socket.id + " disconnected because:");
console.log(reason);
delete users_in_rooms[socket.id];
});
});