将套接字存储为键会产生不正确的值Javascript对象.里面的例子

Storing socket as key yields incorrect value, Javascript Objects. Example inside

本文关键字:Javascript 对象 不正确 存储 套接字      更新时间:2023-09-26

我正在开发一个基本的服务器应用程序,在将套接字(WebSocket)映射到用户时遇到了一些问题。当通过用户的id获得users套接字时,一切都很好,但是当相对于传入数据使用套接字时,它总是拉入添加到键/值对(Javascript对象)的最后一个套接字。

下面是一个(非常混乱)问题的可运行示例。这个可运行的示例需要安装NodeJS和npm包ws

var wss     = require('ws').Server;
var ws      = require('ws');
function User(socket, id, name) {
    this.socket = socket;
    this.id = id;
    this.name = name;
    console.log("new user created: " + name);
}
UserCollection = {
    ids: {},
    sockets: {},
    fetch: function(param) {
        if(param instanceof ws)
            return UserCollection.sockets[param];
        else
            return UserCollection.ids[param];
    },
    put: function(user) {
        UserCollection.sockets[user.socket] = user;
        UserCollection.ids[user.id] = user;
    },
    remove: function(user) {
        if(user === undefined && user == null) return;
        delete UserCollection.sockets[user.socket];
        delete UserCollection.ids[user.id];a
    }
};
var Names = [
    'Chris',
    'Mike'
];
var server          = new wss({port:8080});
server.on('connection', registerSocketEvents);
var chris = new Client(0);
var mike =  new Client(1);
setTimeout(function() {
    chris.send();
}, 2500);
setTimeout(function() {
    mike.send();
}, 3500);
function registerSocketEvents(socket) {
    /**
    * Called whenever the server receives data from a client.
    */
    socket.on('message', function incoming(expectedJson) {
        var data = JSON.parse(expectedJson);
        var req = data.req;
        if(req == 1) {
            // login
            UserCollection.put(new User(socket, data.id, Names[data.id]));
        } else if(req == 2) {
            // test
            console.log("Data received from: (" + UserCollection.fetch(data.id).id + " | " + UserCollection.fetch(socket).id + ") - (" + UserCollection.fetch(data.id).name + " | " + UserCollection.fetch(socket).name + ")");
        }
    });
    /**
    * Called whenever the server loses connection to a client.
    */
    socket.on('close', function close() {
    });
}
function Client(id) {
    this.id = id;
    this.socket = new ws('ws://localhost:8080');
    var self = this;
    this.socket.on('open', function() {
        self.socket.send(JSON.stringify({req: 1, id: id}));
    });
    this.send = function() {
        this.socket.send(JSON.stringify({req: 2, id: this.id}));
    }
}

运行此应用程序得到的结果如下:

new user created: Chris
new user created: Mike
Data received from: (0 | 1) - (Chris | Mike)
Data received from: (1 | 1) - (Mike | Mike)

结果的排序格式如下:

console.log("Data received from: (" + UserCollection.fetch(data.id).id + " | " + UserCollection.fetch(socket).id + ") - (" + UserCollection.fetch(data.id).name + " | " + UserCollection.fetch(socket).name + ")");

数据按顺序发送(Chris->Mike)

在JavaScript中,对象属性标识符是字符串,使用括号中的对象来访问属性会导致对象的"字符串化"并将其用作属性名称。在套接字对象的情况下,您可能会得到所有实例化的相同坐位,从而获得相同的值。

一个简单的解决方案是使用允许将对象用作键的MapWeakMap对象。