Nodejs emitter.setMaxListeners()的问题

Nodejs emitter.setMaxListeners()的问题

我使用exBuffer进行的socket数据分包

var exBuffer = new ExBuffer();
exBuffer.on('data', function(data){
	// do code
})
socketCli.on('data', function(data) {
   exBuffer.put(data);
});

在大并发量下,现在会报错

(node) warning: possible EventEmitter memory leak detected. 31 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
    at Socket.EventEmitter.addListener (events.js:175:15)
    at client.connection (/data/node/online/client.js:57:23)
    at EventEmitter.emit (events.js:96:17)
    at proc (/data/node/node_modules/ExBuffer/ExBuffer.js:151:26)
    at put (/data/node/node_modules/ExBuffer/ExBuffer.js:100:9)
    at Socket.client.connection (/data/node/client.js:96:22)
    at Socket.EventEmitter.emit (events.js:96:17)
    at TCP.onread (net.js:396:14)

使用的nodejs的NET建立socket,socket监听到的消息全部交给exBuffer处理进行分包,解决之前出现的粘包问题。

但是现在会报错,提示监听数量达到了最大值,最开始提示10,我设置为30后,现在又开始报错。


2 回复

Nodejs emitter.setMaxListeners()的问题

背景描述

在处理高并发场景时,你可能会遇到 EventEmitter 监听器数量达到最大限制的问题。这通常会导致内存泄漏警告,并最终影响应用性能。

问题描述

在你的代码中,你使用了一个自定义的 ExBuffer 类来处理从 socket 接收到的数据。你已经设置了 socketCli'data' 事件监听器,当接收到数据时,这些数据被传递给 ExBuffer 进行处理。然而,在高并发情况下,你收到了以下错误信息:

(node) warning: possible EventEmitter memory leak detected. 31 listeners added. Use emitter.setMaxListeners() to increase limit.

解决方案

要解决这个问题,你可以使用 emitter.setMaxListeners() 方法来增加默认的最大监听器数量。默认情况下,每个 EventEmitter 对象的最大监听器数量是 10。你可以通过调用 setMaxListeners(n) 方法来更改这个限制。

示例代码

const EventEmitter = require('events');
const net = require('net');

// 创建一个 EventEmitter 实例
const socketCli = new net.Socket();

// 设置最大监听器数量
socketCli.setMaxListeners(50); // 增加到50

// 使用 ExBuffer 进行数据分包
var exBuffer = new ExBuffer();

// 监听 data 事件
exBuffer.on('data', function(data) {
    // 处理数据
});

socketCli.on('data', function(data) {
    exBuffer.put(data);
});

// 连接到服务器
socketCli.connect({ port: 8080, host: 'localhost' }, () => {
    console.log('Connected to server');
});

// 错误处理
socketCli.on('error', (err) => {
    console.error('Socket error:', err);
});

解释

  1. setMaxListeners:

    • socketCli.setMaxListeners(50)socketCli 的最大监听器数量设置为 50。你可以根据实际需求调整这个数值。
  2. EventEmitter:

    • EventEmitter 是 Node.js 中用于实现事件驱动编程的核心类。它允许对象发出和监听事件。
  3. 数据处理:

    • exBuffer 用于处理接收到的数据,确保数据不会因为网络问题而粘连在一起(即解决粘包问题)。

通过增加最大监听器数量,可以有效避免因监听器过多导致的内存泄漏警告。但需要注意的是,增加监听器数量可能会带来额外的内存消耗,因此需要权衡利弊并选择合适的值。


从你的描述来看,你在使用 Node.js 的 EventEmitter 时遇到了 max listeners 超过的警告。这个警告是因为你添加了超过默认最大数量(默认是10个)的监听器。

EventEmitter 提供了一个方法 setMaxListeners(n) 来增加或修改监听器的最大数量限制。你可以通过这个方法来解决这个问题。

示例代码

const EventEmitter = require('events');
const exBuffer = new (class extends EventEmitter {}).extend();

exBuffer.setMaxListeners(30); // 设置最大监听器数量为30

exBuffer.on('data', function(data) {
    // do code
});

const socketCli = /* 初始化你的 socket */;
socketCli.on('data', function(data) {
    exBuffer.put(data);
});

解释

  1. 创建自定义事件发射器:在这里,我们创建了一个继承自 EventEmitter 的类 exBuffer,并实例化它。这样可以确保 exBuffer 实例拥有 EventEmitter 的所有功能。

  2. 设置最大监听器数量:通过 setMaxListeners(30) 方法,我们将监听器的最大数量设置为30。你可以根据实际需要调整这个数值。

  3. 添加监听器:然后,我们为 exBuffer 添加了一个 'data' 事件的监听器,并将接收到的数据传递给 put 方法。

通过以上步骤,你应该能够避免 EventEmitter 的监听器数量超限的警告。如果问题仍然存在,可能需要进一步检查是否有未移除的事件监听器或其他潜在的内存泄漏问题。

回到顶部