65.9K
CodeProject 正在变化。 阅读更多。
Home

Nodejs 中的会话管理。

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (10投票s)

2012 年 5 月 11 日

CPOL

2分钟阅读

viewsIcon

53431

在本文中,我们将创建一个简单的 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 或角色来管理用户。

© . All rights reserved.