javascript - MaxListenersExceededWarning:检测到可能的 EventEmitter 内存泄漏。添加了 11 个消息列表。使用emitter.setMaxListeners() 增加限制
问题描述
我知道这可能会标记为重复的解决方案,但堆栈溢出的解决方案对我不起作用。
问题
(node:5716) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 message lis
teners added. Use emitter.setMaxListeners() to increase limit.
我的代码库很大,有时我会遇到这个错误,我不知道为什么会这样。我试图增加听众限制,但不幸的是,它不起作用。
const EventEmitter = require('events');
const emitter = new EventEmitter()
emitter.setMaxListeners(50)
更新
浏览一番后,我运行此命令来跟踪警告
node --trace-warnings index.babel.js
原来是我的 socket.io 代码是我将 socket.io 与 Redis 一起使用的问题。这是错误
node:14212) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 message li
steners added. Use emitter.setMaxListeners() to increase limit
at _addListener (events.js:281:19)
at RedisClient.addListener (events.js:298:10)
at Namespace.<anonymous> (D:/newProject/services/socket.js:21:17)
at emitOne (events.js:115:13)
at Namespace.emit (events.js:210:7)
at Namespace.emit (D:\newProject\node_modules\socket.io\lib\namespace.js:213:10)
at D:\newProject\node_modules\socket.io\lib\namespace.js:181:14
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
这是代码(但此代码用于更具体的任务,它不会一直执行)。
const redis = require('redis');
const config = require('../config');
const sub = redis.createClient(config.REDIS.port, config.REDIS.host);
const pub = redis.createClient(config.REDIS.port, config.REDIS.host);
sub.subscribe('spread');
module.exports = io => {
io.on('connection', socket => {
/* To find the User Login */
let passport = socket.handshake.session.passport;
if (typeof passport !== 'undefined') {
socket.on('typing:send', data => {
pub.publish('spread', JSON.stringify(data));
});
sub.on('message', (ch, msg) => {
// This is the Exact line where I am getting this error
io.emit(`${JSON.parse(msg).commonID}:receive`, { ...JSON.parse(msg) });
});
}
});
};
解决方案
Event Emitter的默认限制是 10。您可以使用emitter.setMaxListeners 增加它。我的建议是除非明确要求,否则不要更改它,因为您没有取消订阅,所以听众增加了。现在到你的代码。
const redis = require('redis');
const config = require('../config');
const sub = redis.createClient(config.REDIS.port, config.REDIS.host);
const pub = redis.createClient(config.REDIS.port, config.REDIS.host);
sub.subscribe('spread');
module.exports = (io) => {
io.on('connection', (socket) => {
// this callback will be executed for all the socket connections.
let passport =
socket.handshake.session.passport; /* To find the User Login */
if (typeof passport !== 'undefined') {
socket.on('typing:send', (data) => {
pub.publish('spread', JSON.stringify(data));
});
// this is where you are subscribing for each and every socket connected to your server
sub.on('message', (ch, msg) => {
// this is the Exact line where I am getting this error
// whereas you are emitting messages on socket manager, not on the socket.
io.emit(`${JSON.parse(msg).commonID}:receive`, { ...JSON.parse(msg) });
});
}
});
};
现在,如果我们分析上面的代码,那么如果你打开 20 个到服务器的套接字连接,它将订阅 20 次,这里出错了。现在,如果您的要求是在服务器级别侦听 Redis 上发布的消息,然后在 io 上发出它,那么您的代码应该如下所示
const redis = require('redis');
const config = require('../config');
const sub = redis.createClient(config.REDIS.port, config.REDIS.host);
const pub = redis.createClient(config.REDIS.port, config.REDIS.host);
sub.subscribe('spread');
module.exports = (io) => {
sub.on('message', (ch, msg) => {
// this is the Exact line where I am getting this error
io.emit(`${JSON.parse(msg).commonID}:receive`, { ...JSON.parse(msg) });
});
io.on('connection', (socket) => {
let passport =
socket.handshake.session.passport; /* To find the User Login */
if (typeof passport !== 'undefined') {
socket.on('typing:send', (data) => {
pub.publish('spread', JSON.stringify(data));
});
}
});
};
推荐阅读
- java - SessionNotCreatedException:会话未创建:此版本的 ChromeDriver 仅支持使用 Selenium ChromeDriver 的 Chrome 版本 77
- erlang - 如何为 Ejabberd 自定义模块生成文档?
- java - 如何保存 ArrayList
> 从返回函数? - amazon-web-services - 启动堆栈以启动 ec2 实例时出现“遇到不支持的属性 KeyName”错误
- java - Android:如何在列表视图中的吐司上显示项目 ID?
- wordpress - 我的 Wordpress 在 2 或 3 天后自动更改文件权限
- php - Cakephp 2.x Security::cipher 不提供跨两个应用程序的结果
- javascript - 如何创建链接以下载另一个域上的资源 a href another-sub-domain
- php - 哪个是从 woocommerce_before_calculate_totals 和 woocommerce_product_get_price 更改 woo-commerce 购物车价格的推荐过滤器?
- javascript - 如何通过鼠标单击来中断 ajax 请求