保持对每个用户连接套接字的引用

Keep Reference to Connected Sockets Per User

本文关键字:连接 套接字 引用 用户      更新时间:2023-09-26

我有一个(为了清楚起见)聊天。

用户可以登录,写消息,其他人会看到[name]:[message]

我不想每次写socket.emit('say', message);时都发送用户名和ID因为这是多余的,所以我在服务器上做的是这样的:

var io = require("socket.io").listen(server),
    sockets = {};
io.sockets.on('connection', function (socket){
    socket.on('savePersonToSocket', function(user){
        socket.user = user;
        sockets[user.id] = socket;
    }
    socket.on('doSomething', doSomething);
});
// must be outside of 'connection' since I have TONS of these in a much more 
//complex structure and I don't want to create them all per user connection.
function doSomething(){
    ...
    sockets[userID].emit('foo'); // how to get the userID at this point?
    ...
}

那么,我如何获得userID呢?

指出:

  • 对于每个登录并连接其Facebook帐户的用户,客户端将告诉服务器保存该人的姓名和ID。

我想用一个保存用户名和ID的cookie来做,服务器可以通过读取cookie来知道是哪个用户,但这是一个有点难看的解决方案:每次发送该信息都是多余的。

我还可以劫持'on'函数(以某种方式)并添加功能,将知道它是哪个用户,因为所有'on'侦听器必须驻留在'connection'侦听器中。

可能发生的情况是用户连接到您的聊天应用程序,因此这里

io.sockets.on('connection', function (s){
  socket = s; // cache for later usage

你将"他的套接字"分配给变量socket,它与上下文没有绑定,它是独立的。现在让我们假设第二个用户到达,socket与第二个用户的第二个重新分配,但是如果您获得savePersonToSocket事件,那么socket将被使用,这对每个人都是一样的,更详细地说,它与最后一个连接的用户有关。

你不需要保持对s的引用,当你有很多用户连接到你的应用程序时,你可能不得不处理这个问题,但解决方案将与你的方法大不相同。

编辑:另一种方法可以通过映射用户id和socket s:
// this assumes that the name of a user is unique
var userSocket = {};
io.sockets.on('connection', function (s){
  socket.on('savePersonToSocket', function(user){
    userSocket[user.name] = s;
  }

所以基本上你是说你不想传递给doSomething事件有效载荷的userID ?因为这对我来说是一个有效的解决方案,这不是多余的,这是让服务器知道它正在处理的用户的最简单的方法。其他解决方案可能更优雅,但我怀疑它们是否像这个一样简单和易于维护。

如果可以保存套接字下一个帐户可以坐几个人,例如,这样的系统将是:

var socketsList
io.sockets.on('connection', function (socket) {
   socket.on('auth', function (data) {
      // request to database
    if ( ! (UNIQUE_ID in socketsList)) {
         socketsList[UNIQUE_ID] = {};
         socketsList[UNIQUE_ID][socket.id] = socket;
   });
});
// ONEXIT - BROWSER EVENT
var onExit = function () { socket.emit('exit', { UNIQUE_ID : 123}) }
    window.onunload = onExit;
// 
socket.on('exit', function (data) {
   delete socketsList[UNIQUE_ID][socket.id]
})

如果我说错了请指正

您不能直接保存连接,因为它变化非常频繁。但是,您可以保存socket.id。你有io。sockets。sockets[socketid]这可能就是你要找的。

你可以保存id和名称的数组,如果你喜欢,可以重用它们。

(注意,与过程相关的变量使它不那么可伸缩。但你可以不关心它的长时间的第一次:)

你也有socket相关的存储对象socket.handshakesocket.handshake.somevariable = simple_value_a_string_or_a_number

从理论上讲,像这样难看的东西应该可以工作,但是使用apply是不好的,而且缺乏简单的函数指针使代码更难看

var io = require("socket.io").listen(server);
io.sockets.on('connection', function (socket){
    socket.on('savePersonToSocket', function(user){
        socket.user = usr;
    }
    // No more simple function pointers....
    socket.on('doSomething', function(){
       // pass the Socket as the scope
       doSomething.apply(socket, arguments);
    });
});
function doSomething(){
    ...
    this.emit('foo');
    ...
}

这个怎么样:

var io = require("socket.io").listen(server),
    sockets = {};
io.sockets.on('connection', function (socket){
    socket.on('savePersonToSocket', function(user){
        socket.user = user;
        sockets[user.id] = socket;
    }
    socket.on('doSomething', function() { doSomething(socket.user) });
});
// must be outside of 'connection' since I have TONS of these in a much more 
//complex structure and I don't want to create them all per user connection.
function doSomething(user){
    ...
    sockets[user.id].emit('foo');
    ...
}

我知道你问这个问题已经很长时间了,但就在4年前,我发布了一个node js模块,express和socket。IO,它管理你想要的东西。检查用法和示例,我希望你会发现这个模块有帮助!

你可以通过NPM socket.io.users安装它。io程序。每个客户端一个用户。

你可以看看这个答案的一些用法代码