我想将名为player
的对象关联到不同的套接字。所以我认为最简单的方法就是socket.prototype.player = whatever;
但无论我尝试原型,我都会不断定义。任何人都知道如何实现这一目标?还有IDK,如果这是不好的做法。让我知道。
答案 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)
})
})