node.js服务器端的侦听器太多了?

现在我有听众代码如下。 但是,我的服务器不断告诉我

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit. Trace at EventEmitter.addListener (events.js:160:15) at Hub.<anonymous> (/home/ec2-user/AjaxIM-retail/server/middleware/im/hub.js:88:33) at /home/ec2-user/AjaxIM-retail/server/libs/utils.js:43:23 at IncomingMessage.<anonymous> (/home/ec2-user/AjaxIM-retail/server/libs/authentication/lp/index.js:75:33) at IncomingMessage.EventEmitter.emit (events.js:117:20) at _stream_readable.js:920:16 at process._tickCallback (node.js:415:13) (node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit. 

我读了一些post,有人build议我“不要添加太多的听众”…这是正确的吗? 我该怎么办?

  this.events.addListener('update', o_.bind(function(package) { if(this.clear != 0){ delete this.sessions[this.clear]; } var _package = package.toJSON(); if(package.type == 'status' && package.status == 'offline') { var sids = Object.keys(this.sessions), sid, sess; for(sid in this.sessions) { sess = this.sessions[sid]; if(sess.data('username') == package.username) { if(sess.listeners.length) sess.send(200, {type: 'goodbye'}); delete this.sessions[sid]; break; } } } }, this)); }; Hub.prototype.destroy = function(sid, fn) { this.set(sid, null, fn); }; Hub.prototype.reap = function(ms) { var threshold = +new Date - ms, sids = Object.keys(this.sessions); for(var i = 0, len = sids.length; i < len; ++i) { var sid = sids[i], sess = this.sessions[sid]; if(sess.lastAccess < threshold) { this.events.emit('update', new packages.Offline(sess.data('username'))); } } }; Hub.prototype.get = function(req, fn) { if(this.sessions[req.sessionID]) { fn(null, this.sessions[req.sessionID]); } else { this.auth.authenticate(req, o_.bind(function(data) { if(data) { var session = new User(req.sessionID, data); this.set(req.sessionID, session); this.auth.friends(req, data, o_.bind(function(friends) { var friends_copy = friends.slice(); o_.values(this.sessions).filter(function(friend) { return ~friends.indexOf(friend.data('username')); }).forEach(function(friend) { var username = friend.data('username'); friends_copy[friends_copy.indexOf(username)] = [username, friend.status()]; }, this); session._friends(friends_copy); session.events.addListener('status', o_.bind(function(value, message) { this.events.emit( 'update', new packages.Status(session.data('username'), value, message) ); }, this)); this.events.addListener('update', o_.bind(session.receivedUpdate, session)); this.set(req.sessionID, session); fn(null, session); }, this)); } else { fn(); } }, this)); } }; 

我真的认为这很好。 有什么问题吗? 请指教。 因为我的node.js服务器现在每隔10-20个小时就会崩溃,并且一直在向我抛出这个监听器警告,并且套接字挂起错误,如下所示:

 events.js:72 throw er; // Unhandled 'error' event ^ Error: socket hang up at SecurePair.error (tls.js:999:23) at EncryptedStream.CryptoStream._done (tls.js:695:22) at CleartextStream.read [as _read] (tls.js:496:24) at CleartextStream.Readable.read (_stream_readable.js:320:10) at EncryptedStream.onCryptoStreamFinish (tls.js:301:47) at EncryptedStream.g (events.js:175:14) at EncryptedStream.EventEmitter.emit (events.js:117:20) at finishMaybe (_stream_writable.js:354:12) at endWritable (_stream_writable.js:361:3) at EncryptedStream.Writable.end (_stream_writable.js:339:5) at EncryptedStream.CryptoStream.end (tls.js:633:31) 

这是来自node.js标准库的代码,它触发了这个警告: https : //github.com/joyent/node/blob/master/lib/events.js#L160-L176 。 所以它基本上只是检查你的EventEmitter是否有超过10(默认)的监听器连接。 你可以通过调用setMaxListeners(传递0意味着没有限制)来改变这个值。

所以这个警告本身与这次事故没有任何关系。 但实际上可能是由于泄漏造成的,也就是当你创build一个临时对象,然后附加一个侦听器函数,它捕获一个闭包中的对象,然后不删除侦听器,这导致一个对象永远留在内存中。 也许这是你的情况。 如果不是这样,只要将限制设置为适当的值,如果是这样的话,那么这意味着整个最大听众的事情确实有助于发现泄漏。