微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

node.js – Socket.io断开相关闭包的事件和垃圾收集

我有一个使用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 memory
    footprint doesn’t grow unboundedly

  2. to avoid publishing all the data for
    each 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

你不应该存储它们.把它留在封闭处.然后不需要将它们设置为null.

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所以在每个’update’事件中,你将为进程启动后连接的每个套接字执行这些回调之一,即使是断开连接的套接字.那是你的泄密.相反,对于这种模式,只需在闭包之外设置一次并且只设置一次:

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);
  });
});

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐