Ale*_*lls 4 sockets closures websocket 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));
});
});
}
Run Code Online (Sandbox Code Playgroud)
因此,我的主要问题是,用于闭包的内存量将随套接字连接的数量呈线性增长,并且永远不会停止或减少.socket.io断开事件是否通过垃圾回收释放内存?
似乎我需要重新组织上面的代码来完成两件事:
允许垃圾收集,以便服务器内存占用不会无限增长
避免为每个套接字连接发布所有数据,这就是它现在正在做的事情.
这准确吗?
我遇到的一个问题是,如果套接字连接断开连接,如果在断开连接的套接字上调用emit,同一套接字连接是否会尝试发送消息?换句话说,当您在断开连接的套接字上调用socket.emit()时会发生什么?
否..emit()对断开连接的套接字的任何调用都将被忽略.这是相关的源代码片段.
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
Run Code Online (Sandbox Code Playgroud)
你不应该存储它们.把它留在封闭处.然后不需要将它们设置为null.
因此,我的主要问题是,用于闭包的内存量将随套接字连接的数量呈线性增长,并且永远不会停止或减少.socket.io断开事件是否通过垃圾回收释放内存?
是的,当套接字断开连接时,将发布垃圾收集的东西.socket.io将从它的内部队列中删除它们,没有任何东西可以引用它们,它们将有资格进行垃圾回收.但是,上面的代码与发送事件的方式不一致.请参阅下文了解详情.
ee.on('update',function(data){
socket.emit('update',JSON.stringify(data));
});
Run Code Online (Sandbox Code Playgroud)
不要这样做这种模式.问题是你从来没有removeListener在每个'update'事件上调用这样的事件,你将为进程启动后连接的每个套接字执行这些回调之一,即使是断开连接的套接字.那是你的泄密.相反,对于这种模式,只需在闭包之外设置一次并且只设置一次:
ee.on('update', function (data) {
io.sockets.emit('update', data);
});
Run Code Online (Sandbox Code Playgroud)
(除此之外: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);
});
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1473 次 |
| 最近记录: |