[英]Adding a variable to sockets in socket.io
我想将一个名为player
的对象关联到不同的套接字。 所以我认为最简单的方法就是socket.prototype.player = whatever;
但无论我尝试原型制作什么,我都会变得未定义。 任何人都知道如何做到这一点? 如果这是不好的做法,还有 IDK。 让我知道。
socket.io socket
只是一个 Javascript 对象。 您可以直接向其添加任何属性,而不是通过原型。
因此,在服务器上,您可以直接向socket
对象添加一个新属性:
io.on('connection', function(socket) {
// some code to get the name for this user
var name = .....
socket.player = name;
});
像这样的属性不会与连接的另一端共享——它们对于这个特定对象是本地的,并且只在连接的这一端可用。
由于您确实询问了最佳实践,因此不建议修改不在您控制范围内的类型的原型或在其上使用自定义变量。 尽管 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 没有这样的东西。
截至 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);
};
});
您还可以像这样处理在线用户将他们与他们的套接字 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)
})
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.