7

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

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

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

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?
    ...
}

那么,此时我将如何获取用户 ID?

笔记:

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

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

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

4

6 回答 6

2

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

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

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

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

编辑:另一种方法是映射用户ID和sockets:

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

于 2013-05-18T17:55:33.627 回答
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]
})

如我错了请纠正我

于 2013-05-18T18:05:41.383 回答
1

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

您可以保存 id 和名称的数组并根据需要重复使用它们。

(请注意,与流程相关的变量使其无法扩展。但您第一次可以不关心它:)

你也有与套接字相关的存储对象 socket.handshake socket.handshake.somevariable=simple_value_a_string_or_a_number

于 2013-05-24T18:44:04.160 回答
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');
    ...
}
于 2013-05-26T08:01:42.767 回答
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');
    ...
}
于 2013-05-29T23:31:22.473 回答
0

我知道你问这个问题已经很久了,但就在 4 年前,我发布了一个用于 node js、express 和 socket.io 的模块,它可以管理你想要的东西。检查用法和示例,希望对您有所帮助!

你可以通过 NPM 安装 socket.io.users这是一个用于 socket.io 应用程序的节点 js 模块。每个客户一个用户。

您可以在此答案中查看一些使用代码

于 2015-06-20T19:31:01.313 回答