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

时间:2013-05-18 17:46:55

标签: javascript node.js socket.io

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

用户可以登录,写信息,其他人会看到[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'侦听器中。

6 个答案:

答案 0 :(得分:2)

可能发生的是用户连接到您的聊天应用程序,所以

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事件有效载荷?因为这对我来说似乎是一个有效的解决方案,它不是简化的,它是让服务器知道它正在处理的用户的最简单方法。其他解决方案可能更优雅,但我怀疑它们和这个一样简单易用。

答案 1 :(得分:1)

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

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]
})

如果我错了,请纠正我

答案 2 :(得分:1)

你无法从字面上保存连接,它经常变化。 但是你可以保存socket.id。你有io.sockets.sockets [socketid] 这可能就是你要找的东西。

您可以保存ID和名称数组,并在需要时重复使用它们。

(请注意,与流程相关的变量使其不具有可扩展性。但是您可以在很长时间内不关心它。)

你也有套接字相关的商店对象socket.handshake socket.handshake.somevariable = simple_value_a_string_or_a_number

答案 3 :(得分:1)

理论上,像丑陋这样的东西应该有用,但是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');
    ...
}

答案 4 :(得分:0)

怎么样:

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');
    ...
}

答案 5 :(得分:0)

我知道你问这个问题已经有很长一段时间了,但是4年前我发布了一个节点js,express和socket.io的模块,它管理着你想要的东西。检查用法和示例,希望您会发现此模块有用!

您可以通过NPM socket.io.users This is a node js module for socket.io applications. One user per client.

安装它

您可以浏览一些usage code on this answer