Nodejs MQTT:取消订阅不是一个函数

Nodejs MQTT: unsubscribe is not a function

我很好地实施了 MQTT,但我遇到了 unsubscribe 方法的问题。除此以外,所有其他功能 (mqttCon.publish() , mqttCon.subscribe(), mqttCon.on()...) 都运行良好。我已经检查了拼写,甚至完成了 ctrl +click,它把我带到了库实现,这意味着它是正确的方法并且引用得很好,但我一直收到下面的错误。我该如何解决?

这是行:mqttCon.unsubscribe(topic)

TypeError: mqttCon.unsubscribe is not a function

    at noopHandler (/home/dev/project-dir/src/mqtt/processMessage.js:5:13)
    at module.exports (/home/dev/project-dir/src/mqtt/processMessage.js:10:20)
    at MqttClient.client.on (/home/dev/project-dir/src/mqtt/mqttCon.js:16:13)
    at MqttClient.emit (events.js:189:13)
    at MqttClient._handlePublish (/home/dev/project-dir/node_modules/mqtt/lib/client.js:1271:12)
    at MqttClient._handlePacket (/home/dev/project-dir/node_modules/mqtt/lib/client.js:410:12)
    at work (/home/dev/project-dir/node_modules/mqtt/lib/client.js:321:12)
    at Writable.writable._write (/home/dev/project-dir/node_modules/mqtt/lib/client.js:335:5)
    at doWrite (/home/dev/project-dir/node_modules/mqtt/node_modules/readable-stream/lib/_stream_writable.js:428:64)
    at writeOrBuffer (/home/dev/project-dir/node_modules/mqtt/node_modules/readable-stream/lib/_stream_writable.js:417:5)

注意:我使用的是 ES6(Emacscript 6+) javascript 和 not 打字稿。 节点 12.18.1 和 npm 6.14.6

这是我的连接代码mqttCon.js:

const mqtt = require('mqtt')
const processMessage = require('./processMessage')
const logger = require('../logConf')
const options = {
    host: '',
    port: '',
    username:'',
    password: '',
    protocol: ''
};
const client = mqtt.connect(options)
client.on("connect", function () {
    console.log("MQTT connected  with status: " + client.connected);
    if (client.connected) {
        client.on('message', (topic, message) => {
            processMessage(topic, String(message))
        })
    }
})
client.on('error', error => {
    console.log(error,'ERROR')
    logger.errorLogger.error(error)
})
client.on('reconnect', error => {
    console.log(error,'RECONNECT')
    logger.errorLogger.error(error)
})
client.on('close', error => {
    console.log(error,'CLOSE')
    logger.errorLogger.error(error)
})
client.on('disconnect', error => {
    console.log(error,'DISCONNECT')
    logger.errorLogger.error(error)
})
client.on('offline', error => {
    console.log(error,'OFFLINE')
    logger.errorLogger.error(error)
})
module.exports = client

这是 processMessage.js :

const mqttCon = require('./mqttCon')
const logger = require('../logConf')
let noopHandler = (topic, message) => {
    console.log(String(message))
    mqttCon.unsubscribe(topic)    //THIS IS WHERE THE ERROR IS OCCURRING *******************
}
module.exports = (topic, message) => {
    switch (topic) {
        case 'NOOOOOOOOOOOOOOOOOOOOOOOOP':
            return noopHandler(topic, message)
        case 'anotherTopic':
            // return handleAnotherTopic(String(message))
            return
        default:
            logger.errorLogger.error(new Error(`No handler for topic ${topic}`))

    }
}

您的mqttCon.js文件没有client.prototype.unsubscribe = function() {},所以错误是正确的。您将 client 定义为模块,但您确实需要在某处调用 mqtt.unsubscribe()。因此,您需要将 unsubscribe() 函数添加到 client 常量(在这种情况下实际上应该是 var),或者在需要 mqtt 后调用 mqtt.unsubscribe() 函数你的 processMessage.js 文件中的模块....我认为这与你试图做的事情背道而驰。您可能想进一步了解 module.exports 的实际工作原理:https://www.sitepoint.com/understanding-module-exports-exports-node-js/

更新: 以上影响了我的想法,问题是我正在导入 processMessage.js ,而 processMessage.js 又导入了 mqttCon.js 。循环导入,意味着 mqttCon(mqttClient) 始终未在 processMessage.js 内初始化。解决方案是当客户端已经初始化并导出为如下模块时,我在 client.on('connect'....)... 块中导入了 processMessage.js


client.on("connect", () => {
    console.log("MQTT connected  with status: " + client.connected);
    if (client.connected) {
        client.on('message', (topic, message) => {
            require('./processMessage')(topic, String(message))
        })
    }
})