将一个变量添加到socket.io中的套接字

时间:2016-06-06 07:31:00

标签: javascript node.js socket.io

我想将名为player的对象关联到不同的套接字。所以我认为最简单的方法就是socket.prototype.player = whatever;

但无论我尝试原型,我都会不断定义。任何人都知道如何实现这一目标?还有IDK,如果这是不好的做法。让我知道。

4 个答案:

答案 0 :(得分:7)

socket.io socket只是一个Javascript对象。您可以直接向其添加任何属性,而不是通过原型。

因此,在服务器上,您可以直接向socket对象添加新属性:

io.on('connection', function(socket) {
    // some code to get the name for this user
    var name = .....
    socket.player = name;
});

这样的属性不与连接的另一端共享 - 它们是此特定对象的本地对象,仅在连接的这一侧可用。

答案 1 :(得分:0)

截至2017年12月的解决方案(socket.io内部变化的频率超出了人们的假设)。在这个版本中,我创建了一个join_exclusive函数,除了默认房间和你要加入的新房间外,它将留下所有房间

io.sockets.on('connection', function(socket) {
    socket.join_exclusive = function (newroom) {
        for (var room in this.manager.roomClients[this.id]) {
            if (room == '') continue; // default room required for socket.emit(...
            this.leave(room.slice(1)); // remove '/' char
        }
        this.join(newroom);
    };
});

答案 2 :(得分:0)

由于您确实询问了最佳实践,因此不建议您修改不在您控制范围内的类型的原型,也不要在其顶部使用自定义变量。尽管JavaScript相当宽松,可以让您进行这些更改,但您应避免对Socket.IO将来可能对原型进行的任何进一步更改。

原因是,无论您使用什么属性名称,总是有发生冲突的可能性,尽管很小。

要解决此问题,我们可以使用与套接字ID相关的Map,也可以在套接字本身上使用WeakMap。如果使用Map,则必须在套接字断开连接时手动删除该条目,但是使用WeakMap时,它将自动进行垃圾回收(假定SocketIO在断开连接时释放对它的所有引用)。

  /** @type {WeakMap<SocketIO.Socket, Object>} */
  const socketIOLocals = new WeakMap();
  io.use((socket, next) => {
      const locals = { player: null }; // Create new instance
      socketIOLocals.set(socket, locals);
      next();
  });

然后您可以使用socketIOLocals.get(socket);

获取变量对象。

另一方面,Express确实具有.locals属性,可让您在Response个对象之间传递数据。可惜SocketIO没有这样的东西。

答案 3 :(得分:0)

您还可以像这样处理在线用户将其与套接字ID配对

io.on('connection', function(socket){
  socket.on('disconnect', function() {
    console.log("disconnect")
    for(var i = 0; i < onlineplayers.length; i++ ){
      if(onlineplayers[i].socket === socket.id){
        console.log(onlineplayers[i].code + " just disconnected")
        onlineplayers.splice(i, 1)
      }
    }
    io.emit('players', onlineplayers)
  })

  socket.on('lobby_join', function(player) {
    if(player.available === false) return
    var exists = false
    for(var i = 0; i < onlineplayers.length; i++ ){
      if(onlineplayers[i].code === player.code){
        exists = true
      }
    }
    if(exists === false){
      onlineplayers.push({
        code: player.code,
        socket:socket.id
      })
    }
    io.emit('players', onlineplayers)
  })

  socket.on('lobby_leave', function(player) {
    var exists = false
    for(var i = 0; i < onlineplayers.length; i++ ){
      if(onlineplayers[i].code === player.code){
        onlineplayers.splice(i, 1)
      }
    }
    io.emit('players', onlineplayers)
  })
})