I know this might flag as a duplicate solution but the solution on stack overflow is not working for me.
Problem
(node:5716) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 message lis teners added. Use emitter.setMaxListeners() to increase limit.
My codebase is huge and I facing this error sometimes I don't know why it is happening. I tried to increase the listeners limit but unfortunately, it is not working.
const EventEmitter = require('events'); const emitter = new EventEmitter() emitter.setMaxListeners(50)
UPDATE
After Some browsing, I run this command to trace warning
node --trace-warnings index.babel.js
Turns out be my socket.io code is the problem I am using socket.io with Redis. This is the error
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)
this is the code (But this code is for more specific tasks it will not execute all the time).
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) }); }); } }); };
The warning possible EventEmitter memory leak detected happens when you have more than 10 listeners (read EventEmitter) attached to an event. First of all, try to understand how this can be the case. Most of the times it's a developer mistake that can be solved easily by cleaning up the code.
on(event, listener) and eventEmitter. addListener(event, listener) are pretty much similar. It adds the listener at the end of the listener's array for the specified event. Multiple calls to the same event and listener will add the listener multiple times and correspondingly fire multiple times.
EventEmitter3 is a high performance EventEmitter. It has been micro-optimized for various of code paths making this, one of, if not the fastest EventEmitter available for Node. js and browsers. The module is API compatible with the EventEmitter that ships by default with Node.
Any listeners for the error event should have a callback with one argument to capture the Error object and gracefully handle it. If an EventEmitter emits an error event, but there are no listeners subscribed for error events, the Node. js program would throw the Error that was emitted.
The default limit for Event Emitter is 10. You can increase it with the emitter.setMaxListeners. My suggestion is not to change it unless and until explicitly required, listeners are increased because you didn't unsubscribe. Now to your code.
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) }); }); } }); };
Now if we analyze the above code then if you open 20 socket connections to your server it will subscribe 20 times, here it is going wrong. Now if your requirement is to listen for the message published on Redis at the server level and then emit it on io then your code should be like below
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)); }); } }); };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With