我在nodejs中使用ws模块作为Web套接字服务器,代码的简化版本如下:
var WebSocketServer = require('ws').Server
var wss = new WebSocketServer({port: 9001});
wss.on('connection', function (ws) {
// is the ws object created here ?
ws.on('message', function (message) {
if (message[0] === '+') {
ws.name = message.substring(1);
console.log(ws.name+' connected');
}
});
ws.on('close', function () {
console.log(ws.name+' disconnected');
// Will this ws object be deleted ?
});
});
我想知道:
最重要的是: 如果大量客户端断开连接并且ws对象一直处于垃圾收集状态,那么当垃圾收集发生时,我的服务器可能会被锁定很长一段时间了吗? 我是否应该在将这些ws对象存储到另一个对象时遇到麻烦,所以我可以使用delete关键字并在收到close事件后立即将其删除?
如果我这样做,我可能会有点像这样:
var WebSocketServer = require('ws').Server
var wss = new WebSocketServer({port: 9001});
var websockets = {};
wss.on('connection', function (ws) {
ws.on('message', function (message) {
if (message[0] === '+') {
ws.name = message.substring(1);
websockets[ws.name] = ws; // Add to the object that stores ws objects
console.log(ws.name+' connected');
}
});
ws.on('close', function () {
delete websockets[ws.name]; // Delete from the object
console.log(ws.name+' disconnected');
});
});
那么,值得吗?我在第二个片段中写了更多垃圾收集友好代码吗?当垃圾收集发生时,它是否有助于避免长时间锁定?
更新:对不起,我刚刚意识到第二段代码是多么愚蠢。我实际上在websockets[ws.name] = ws
时复制了对象的数量......但问题的第一部分仍然有效。
答案 0 :(得分:4)
在每个连接事件上,是否创建了一个ws对象?
是
每个连接的客户端中的一个对象是否在RAM中持续存在,直到它被垃圾收集?
是的,对于每个 JavaScript对象都是如此。
我是否应该解决将这些ws对象存储在另一个对象中的问题,因此我可以使用delete关键字并在收到关闭事件后立即将其删除?
没有。使用delete
关键字不会释放你的记忆。事实上,除了删除引用之外,它什么也没做。考虑这个例子:
var x = { };
var y = { };
var z = { };
x.test = z;
y.test = z;
delete x.test;
您可以看到x.test
已删除(对象x
不再具有.test
属性),但z
根本未删除,因为y
保留对z
的引用。
您认为WS如何使用多个ws
对象?它将它们存储在内部某处。如果要删除ws
对象,只需执行
ws.on('close', function () {
delete ws;
});
这将确保垃圾收集器在某些时候收集ws
。另一方面,我认为WS
已经在内部处理了这个问题,所以你根本不用担心它。
旁注:无法在JavaScript中触发垃圾收集器。但不要担心。如果达到内存限制,它将自行启动。