NodeJS + MQTT - публикация с частотой 1 мс вызывает утечку памяти EventEmitter - PullRequest
0 голосов
/ 21 июня 2020

Я хочу имитировать большое количество сообщений, поэтому я использовал это в своем index.js. Я использую модуль mqtt.

var client = mqtt.connect('mqtts://broker.com:8883', {
  ca: [fs.readFileSync('broker.pem')],
  rejectUnauthorized: false
})

let frequency = process.env.FREQUENCY || 1000
client.on('connect', function () {
  let count = 0
  setInterval(() => {
    process.stdout.clearLine()
    process.stdout.cursorTo(0)
    client.publish('/topic/string', JSON.stringify(getPayload()), (err) => {
      if (err) {

      } else {
        ++count
        process.stdout.write('Messages published :' + count)
      }
    })
  }, frequency)
})

Когда я запускаю его как export FREQUENCY=1 && node index.js, я получаю эту ошибку.

nsubrahm@nsubrahm simulator % node index.js     
(node:2313) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 1001 drain listeners added. Use emitter.setMaxListeners() to increase limit
MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 1001 drain listeners added. Use emitter.setMaxListeners() to increase limit
    at _addListener (events.js:243:17)
    at TLSSocket.addListener (events.js:259:10)
    at TLSSocket.Readable.on (_stream_readable.js:799:35)
    at TLSSocket.once (events.js:290:8)
    at sendPacket (/my/simulator/node_modules/mqtt/lib/client.js:99:19)
    at MqttClient._sendPacket (/my/simulator/node_modules/mqtt/lib/client.js:1061:7)
    at MqttClient.publish (/my/simulator/node_modules/mqtt/lib/client.js:541:14)
    at Timeout.setInterval [as _onTimeout] (/my/simulator/index.js:53:12)
    at ontimeout (timers.js:436:11)
    at tryOnTimeout (timers.js:300:5)

Я даже пробовал запустить 5 экземпляров index.js с частотой 5 секунд каждый; так что в целом я вижу поведение нагрузки, близкое к 1 мс. Та же ошибка.

Как смоделировать клиента, который выполняет MQTT publi sh с частотой 1 мс?

1 Ответ

0 голосов
/ 21 июня 2020

Кажется, проблема не в коде, даже установка переменной частоты с 1 у меня сработала, потому что я могу видеть сообщение в консоли без предупреждений, возможно, другая часть кода, такая как getPayload (), создает много слушателей, и это может вызвать предупреждение.

Попробуйте ограничить количество слушателей, которые могут быть созданы с помощью клиентской переменной, и установите простой текст в client.publish('/topic/string', JSON.stringify(getPayload()), следующим образом:

...
var client = mqtt.connect('mqtts://broker.com:8883', {
  ca: [fs.readFileSync('broker.pem')],
  rejectUnauthorized: false
})
/** This will avoid the MaxListenerExceededWarning */
client.setMaxListeners(100)
...

...
// Do not use JSON.stringify(getPayLoad())
client.publish('/topic/string', 'JUST_TYPE_THIS', (err) => { ...
...

Это проблема объясняется здесь

Обновление

Фрагмент кода, предотвращающий предупреждение об утечке памяти

var mqtt = require('mqtt')
// Changed URL
var client  = mqtt.connect('mqtt://test.mosquitto.org')

// IMPORTANT: Limit listeners
client.setMaxListeners(100)

// Changed ms to 1 ms for this example
//let frequency = process.env.FREQUENCY || 1000
let frequency = 1

client.on('connect', function () {
  let count = 0
  setInterval(() => {
    process.stdout.clearLine()
    process.stdout.cursorTo(0)
    // Set harcoded key-value but you need to set
    // real key-value
    client.publish('/topic/string', 'key-value-example', (err) => {
      if (err) {

      } else {
        ++count
        process.stdout.write('Messages published :' + count)
      }
    })
  }, frequency)
})

...