在socket.io中管理用户
我正在用socket.io编写一个游戏,为了管理游戏中的两名玩家,我有如下内容:在socket.io中管理用户,socket.io,Socket.io,我正在用socket.io编写一个游戏,为了管理游戏中的两名玩家,我有如下内容: let user1 = 1; let user2 = 2; io.on('connection', function(socket){ if (user1 === 1) user1 = socket; else if (user2 === 2) user2 = socket; socket.on('user_does_something', function(){ if
let user1 = 1;
let user2 = 2;
io.on('connection', function(socket){
if (user1 === 1) user1 = socket;
else if (user2 === 2) user2 = socket;
socket.on('user_does_something', function(){
if (user1 === socket) {
//do something for user1
}
if (user2 === socket) {
//do something for user2
}
});
socket.on('disconnect', function () {
if (user1 === socket) user1 = 1;
if (user2 === socket) user2 = 2;
});
});
它是可行的,但这似乎是一种糟糕的方法,有没有简单的方法可以做到这一点?这种方法是不可扩展的,因为您目前仅限于两个并发用户,这意味着如果您希望实现某种形式的大厅系统,即使您将两个并发用户限制在一个游戏中,您也只能运行一个并发游戏 相反,我建议使用
Map()
,您可以使用它来存储包含当前连接的客户机信息的客户机对象。您可以使用套接字对象的属性,例如socket.id
,为每个用户形成标识符。另一个注意事项是,当我们传入socket
对象时,我们已经知道事件是从哪个连接的用户派生的,因此当user one发出事件时,我们可以使用对象的id
属性找到哪个用户发出了事件,如下所示
socket.on('user_does_something', function(){
if (user1 === socket) {
//do something for user1
}
if (user2 === socket) {
//do something for user2
}
});
此函数可以重构为
let connectedUserMap = new Map();
io.on('connection', function(socket){
let connectedUserId = socket.id;
connectedUserMap.set(socket.id, { status:'online'});
socket.on('user_does_something', function(){
//do something
});
}
这种处理用户的方法非常优越,因为您已经知道连接的用户,并且它减少了识别事件来源所需的逻辑
如果需要,我可以编写一个更好的示例,但这应该有助于改进代码
更新:
后端代码
let connectedUserMap = new Map();
io.on('connection', function(socket){
let connectedUserId = socket.id;
//add property value when assigning user to map
connectedUserMap.set(socket.id, { status:'online', name: 'none' });
socket.on('recieveUserName', function(data){
//find user by there socket in the map the update name property of value
let user = connectedUserMap.get(connectedUserId);
user.name = data.name;
});
}
前端发射:
emit('recieveUserName', {
//normally this would be dynamically added based on user input, but for examples sake
name: 'user1'
});
为清晰起见,带有两个额外功能的长格式示例:
let connectedUserMap = new Map();
io.on('connection', function(socket){
let connectedUserId = socket.id;
//add property value when assigning user to map
connectedUserMap.set(socket.id, { status:'online', name: 'none' });
socket.on('user_does_something', function(){
//get access to the user currently being used via map.
let user = connectedUserMap.get(connectedUserId);
//do something.
});
//sets the user name for the user.
socket.on('recieveUserName', function(data){
//find user by there socket in the map the update name property of value
let user = connectedUserMap.get(connectedUserId);
user.name = data.name;
});
socket.on('disconnect', function () {
//get access to the user currently being used via map.
let user = connectedUserMap.get(connectedUserId);
user.status = 'offline';
});
socket.on('someEventForAEveryone', function (data) {
//data.msg - message to be output
io.emit('message', "this is a test");
});
//example of sending another user a message
//https://gist.github.com/alexpchin/3f257d0bb813e2c8c476 - reference
socket.on('sendOtherClientMessage', function (data) {
//data.id - the user to emit to.
if(connectedUserMap.has(data.id)){
socket.broadcast.to(data.id).emit('message', 'for your eyes only');
} else {
console.log("Client is currently not connected.");
}
})
};
假设用户发送了他们的名字,我想把它分配给socket.on('name',function(name){…})中的用户名变量;这看起来像什么?我已经更新了我的答案,显示了如何使用我上面概述的结构将名称分配给用户@Orion@Orion我刚刚更新了它,我已经完全重写了您现有的代码,并添加了两个函数以使其更清晰,希望这能让您开始:-)另一个问题,我如何在断开连接时从映射中删除该用户?@Orion您可以使用
connectedUserMap.delete(connectedUserId)
删除带有socketId的条目。