Nodejs 中的会话管理。






4.75/5 (10投票s)
在本文中,我们将创建一个简单的 WebSocket 会话管理模块,用于 Nodejs,以帮助我们进行下一个项目。
引言
如你所知,我们可以使用 Socket.io 模块通过 Nodejs 运行 WebSocket 服务器。在 socket.io 服务器中的主要问题是如何管理会话和用户。在本文中,我们将创建一个简单的 Nodejs 模块来帮助我们解决这个问题。
我们开始吧!
Socket IO
每当用户连接到 Socket.io 服务器时,服务器将创建一个具有唯一 ID 的会话,这对于单播至关重要。以下是一个示例代码,展示了 socket.io 的工作方式;但有关更多信息,请访问 socket.io
// Load an instance of the Socket.io module
// It will listen to port no. 3000 for connections
var io = require('socket.io').listen(3000);
// Tells the application what to do whenever
// a new client connects to the server
io.sockets.on('connection', function (socket) {
// Send some data to the user
socket.emit('news', { hello: 'world' });
// Listen to the event named "my other event"
socket.on('my other event', function (data) {
// Log the recieved data in the application console
console.log(data);
});
});
在此示例中,我们将仅为每个会话存储用户名、用户 ID 和角色。
这是我们的角色列表:
var userRoles = {
Admin: "administrator",
User: "user",
Supervisor: "supervisor"
};
现在,让我们编写我们的会话管理类,然后将其转换为 Nodejs 模块。
sessionManagement.js:
var sessionManagement = {
};
对于这样的模块,我们需要执行以下操作
- 添加/删除用户
- 按 ID 查找会话
- 按用户 ID 查找会话
- 检查权限
首先,我们需要存储数据。我更喜欢使用简单的数组,因为它们速度快且易于使用。
你可能会问“如果服务器崩溃了怎么办?!” 嗯,我说如果服务器崩溃,所有会话都会丢失并重新创建;但如果你出于任何原因需要数据,我建议使用 mongoose,它是 Nodejs 的 MongoDB 模块。
我将把数组放在类作用域之外,以提高安全性。
var sessions = [];
var sessionManagement = {
};
除了上述方法之外,我们需要一个方法来查找给定用户 ID 的索引,这样我们就无需每次都编写代码。
function(sessionId) {
for(var i in sessions) {
if(sessions[i].sessionId == sessionId)
return i;
}
}
这是我们的完整脚本 (sessionManagement.js)
var sessions = [];
//User roles list
var userRoles = {
Admin: "administrator",
User: "user",
Supervisor: "supervisor"
};
var sessionManagement = {
indexOf: function(sessionId) {
for(var i in sessions) {
if(sessions[i].sessionId == sessionId)
return i;
}
return null;
},
indexOfUser: function(userId) {
for(var i in sessions) {
if(sessions[i].userId == userId)
return i;
}
return null;
},
add: function(sessionData) {
sessions.push(sessionData);
},
remove: function(sessionId) {
var index = this.indexOf(sessionId);
if(index != null) {
sessions.splice(index, 1);
} else {
return null;
}
},
removeByUserId: function(userId) {
var index = this.indexOf(userId);
if(index != null) {
sessions.splice(index, 1);
} else {
return null;
}
},
getSessionById: function(userId) {
var index = this.indexOfUser(userId);
if(index != null) {
return sessions[index];
} else {
return null;
}
},
getSessionByUserId: function(sessionId) {
var index = this.indexOfUser(userId);
if(index != null) {
return sessions[index];
} else {
return null;
}
},
isAdmin: function(userId) {
var index = this.indexOfUser(userId);
if(index != null) {
if(users[index].role == userRoles.Admin) {
return true;
} else {
return false;
}
} else {
return null;
}
},
getUsersByRole: function(role) {
var usersByRole = [];
for(var i in users) {
if(users[i].role == role)
usersByRole.push(users[i]);
}
return usersByRole;
}
};
现在,是时候将其转换为 Nodejs 模块了……
如 Nodejs 手册 中所述,我们必须将任何所需的对象添加到 module.exports
对象中,才能在另一个模块或脚本中使用它。因此,我们只需要将我们的类分配给这个变量
module.exports = sessionManagement;
完成了!
现在,我们可以通过将 sessionManagement.js 放在我们的应用程序目录或 node_modules
目录中,在任何所需的脚本中使用该模块。
使用示例
var sessionMgm = require("sessionManagement");
io.sockets.on('connection', function (socket) {
socket.on('setUserInfo', function (data) {
var sess = new Object();
sess.sessionId = socket.id;
sess.userId = data.userId;
sess.username = data.username;
sess.role = data.role;
sessionMgm.add(sess);
});
socket.on('sendPm', function(data) {
if(data != null) {
var user = sessionMgm.getSessionByUserId(data.userId);
if(user != null) {
io.sockets.socket(user.sessionId).emit('newMessage', data.message);
} else {
var sysMsg = {type: "error", message: "User not found!"};
socket.emit('systemMessage', sysMsg);
}
}
});
socket.on('disconnect', function() {
sessionMgm.remove(socket.id);
});
}
结论
Socket.io 为每个会话分配一个唯一的 ID。要直接向特定用户发送事件,我们需要知道他们的会话 ID。我们编写了一个类来管理这些会话,然后将其转换为 Nodejs 模块,以便在我们的下一个应用程序中更简单地使用它。使用此模块,我们可以简单地通过会话 ID、用户 ID 或角色来管理用户。