Nan*_*ane 8 javascript mysql node.js reactjs
我知道这可能会标记为重复的解决方案,但堆栈溢出的解决方案对我不起作用.
问题:
(node:5716) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 message lis
teners added. Use emitter.setMaxListeners() to increase limit.
Run Code Online (Sandbox Code Playgroud)
我的代码库是巨大的,我面对这个错误有时我不知道为什么会发生
我尝试了什么:
试图增加听众的限制,但遗憾的是它无法正常工作.
const EventEmitter = require('events');
const emitter = new EventEmitter()
emitter.setMaxListeners(50)
Run Code Online (Sandbox Code Playgroud)
更新:
经过一些浏览后,我运行此命令来跟踪漫游
node --trace-warnings index.babel.js
Run Code Online (Sandbox Code Playgroud)
结果是我的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)
Run Code Online (Sandbox Code Playgroud)
这是代码(但是这段代码用于更具体的任务,它不会一直执行)
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) => {
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))
});
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)})
})
}
});
};
Run Code Online (Sandbox Code Playgroud)
use*_*584 15
MaxListenersExceededWarning:检测到可能的 EventEmitter 内存泄漏。添加了11 条消息列表。使用emitter.setMaxListeners()来增加限制
默认情况下,任何单个事件最多可以注册10 个监听器,我们得到了11 个Ohno
// Change to 80 or 150 whatever and see what happens
require('events').EventEmitter.prototype._maxListeners = 70;
require('events').defaultMaxListeners = 70;
process.on('warning', function (err) {
if ( 'MaxListenersExceededWarning' == err.name ) {
console.log('o kurwa');
// write to log function
process.exit(1); // its up to you what then in my case script was hang
}
});
Run Code Online (Sandbox Code Playgroud)
中的内置events模块node.js(如果您使用webpack或编译,则该模块的版本捆绑到您的前端应用程序中browserify)对您的代码做出一些假设。有时,在某个地方,有人认为如果您X注册了多个侦听器,那么您肯定会出现内存泄漏。有时它是正确的,并正确地提醒您去查找泄漏。
我多次收到此警告,但通常只有两个特定原因,两者都有简单的解决方案:
您的组件可能看起来像这样,您使用组件方法作为事件侦听器,并在注册时绑定它。
import events from '../lib/events' // some singleton event emitter
class MyComponent extends React.Component {
componentDidMount() {
events.addEventListener('some-event', this.myMethod.bind(this))
}
componentWillUnmount() {
events.removeEventListener('some-event', this.myMethod.bind(this))
}
myMethod() {
// does something
}
render() {
// gotta have this too
}
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是每次都会function.bind创建一个新函数,因此您尝试删除的函数与您添加的函数不同。因此,添加的函数不断增加(糟糕的双关语),实际上确实存在内存泄漏。
尽早绑定您的方法,通常在constructor(). 然后每次都可以参考绑定的版本,保证删除的功能和添加的功能一样。
import events from '../lib/events' // some singleton event emitter
class MyComponent extends React.Component {
constructor() {
// bind your method early so the function removed
// is the same as the function added
this.myMethod = this.myMethod.bind(this)
}
componentDidMount() {
events.addEventListener('some-event', this.myMethod)
}
componentWillUnmount() {
events.removeEventListener('some-event', this.myMethod)
}
myMethod() {
// does something
}
render() {
// gotta have this too
}
}
Run Code Online (Sandbox Code Playgroud)
有时你真的做了功课,仔细检查你是否根据需要提前绑定了你的听众,然后在适当的地方把它们全部删除。然后你仔细观察,发现你正在做这样的事情:
import MyComponent from './MyComponent' // same component above
class Parent extends React.Component {
render() {
return (
<div>
{ this.props.largeArray.map(MyComponent) }
</div>
)
}
}
Run Code Online (Sandbox Code Playgroud)
假设this.props.largeArray有 50、100 或 250 个元素。这意味着(按照设计!)您正在渲染 250 个实例MyComponent,每个实例都注册另一个唯一的事件侦听器。
不要害怕!这是完全有效的代码,没有内存泄漏。但它确实突破了最大侦听器限制,即有人在某个时间、某个地方任意决定帮助保护您。
eventemitter3如果你决定你已经完成了你的作业,并仔细检查了所有的事情,并且(按照设计!)注册了大量的事件监听器,那么最简单的解决方案是切换到 using eventemitter3,这是一个直接替代node 的events模块,除了速度更快,与浏览器兼容,并且不会为您设置最大侦听器限制。
用法就像内置events模块:
const EventEmitter = require('eventemitter3')
const emitter = new EventEmitter()
Run Code Online (Sandbox Code Playgroud)
事件发射器的默认限制为10。您可以使用generator.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) => {
//COMMENT : 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))
});
// COMMENT : This is where you are subscribing for each and every socket conected to your server
sub.on('message',(ch,msg) => { // this is the Exact line where I am getting this error
//COMMENT : Where as you are emiting message on socket manager not on socket.
io.emit(`${JSON.parse(msg).commonID}:receive`,{...JSON.parse(msg)})
})
}
});
};Run Code Online (Sandbox Code Playgroud)
现在,如果我们分析以上代码,则如果您打开与服务器的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))
});
}
});
};Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13662 次 |
| 最近记录: |