gpt4 book ai didi

node.js - Socket.io 断开事件和相关关闭的垃圾回收

转载 作者:搜寻专家 更新时间:2023-10-31 23:00:39 24 4
gpt4 key购买 nike

我有一个使用 socket.io 的基本实时服务器。我的问题涉及闭包和垃圾收集,以及我是否应该费心将套接字连接存储在关联数组中,还是将其留给闭包来管理连接。

我的一个问题是,如果套接字连接断开,如果在断开连接的套接字上调用 emit,同一个套接字连接是否会尝试发送消息?换句话说,当您在断开连接的套接字上调用 socket.emit() 时会发生什么?

下面是一些代码,问题在底部:

 var socketio = require('socket.io');
var io = socketio.listen(server);
var EE = require('events').EventEmitter;
var ee = new EE(); //this is actually initialized elsewhere but now you know what it is

var connectedUsers = {}; //associative array to store socket connections by socket.id

io.on('connection', function (socket) {

connectedUsers[socket.id] = socket; //should I bother storing the socket connections in the associative array or just leave it to the closure to store them

socket.on('disconnect', function () {
connectedUsers[socket.id] = null; //should I bother removing
});

ee.on('update',function(data){

socket.emit('update',JSON.stringify(data));

});

ee.on('insert',function(data){

socket.emit('insert',JSON.stringify(data));

});

ee.on('delete',function(data){

socket.emit('delete',JSON.stringify(data));

});
});
}

所以我的主要问题/担忧是,用于闭包的内存量将随着套接字连接数线性增长,并且永远不会停止或减少。 socket.io 断开连接事件是否通过垃圾回收释放内存?

看来我需要重新组织上面的代码来完成两件事:

  1. to allow for garbage collection so that the server memoryfootprint doesn't grow unboundedly

  2. to avoid publishing all the data foreach and every socket connection, which is what it is doing now.

这准确吗?

最佳答案

One question I have is if a socket connection disconnects, will the same socket connection attempt to send a message if emit is invoked on the disconnected socket? In other words, what happens when you call socket.emit() on a disconnected socket?

没有。在断开连接的套接字上对 .emit() 的任何调用都将被忽略。 Here's the relevant source code snippet .

connectedUsers[socket.id] = socket;
//should I bother storing the socket connections in the
// associative array or just leave it to the closure to store them

你不应该存储它们。把它留给关闭。然后以后就不需要将它们设置为空了。

So my primary question/concern is that the amount of memory used for the closures will grow linearly with the number of socket connections and will never stop or decrease. Do socket.io disconnect events release memory via garbage collection?

是的,当套接字断开连接时,东西将被释放用于垃圾回收。 socket.io 将从其内部队列中删除它们,不再有任何引用它们,并且它们将有资格进行垃圾收集。但是,您上面的代码对于发送事件的方式不正确。详情请见下文。

ee.on('update',function(data){
socket.emit('update',JSON.stringify(data));
});

不要这样做。问题是您永远不会调用 removeListener,因此在每个“更新”事件中,您将为自进程启动以来曾经连接过的每个套接字执行这些回调之一,甚至是断开连接的套接字。那是你的泄漏。相反,对于这种模式,只需在闭包之外设置一次广播:

ee.on('update', function (data) {
io.sockets.emit('update', data);
});

(另外:JSON.stringify 几乎肯定是不必要的。只有当你真的知道你必须在另一边将它作为字符串获取时才这样做。只发出一个对象可能是正确的)

现在对于需要发送到特定套接字而不是所有连接的套接字的情况,您应该使用命名函数,这样您就可以将每个 ee.on 与相应的 配对ee.removeListener 以正确防止幻听。

io.on('connection', function(socket) {
// every socket gets a closure
// and a distinct onUpdate function object
function onUpdate(data) {
socket.emit('update', data);
}
ee.on('update', onUpdate);

socket.on('disconnect', function() {
// removes the handler for this specific socket,
// leaving the others intact
ee.removeListener('update', onUpdate);
});
});

关于node.js - Socket.io 断开事件和相关关闭的垃圾回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31689098/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com