Node.js Mqtt 客户端:匹配主题

Node.js Mqtt client : matched topic

我有来自 mqtt 节点模块的 mqtt 客户端。

我订阅了主题例如topic1/#, topic2/#

当有人发布到 topic2/165(例如)时,我想知道订阅的主题 "topic2/#" 是否匹配。

有简单的方法吗?

使用正则表达式

client.on('message', function (topic, message) {
  var topic1_re = /^topic2\/.*/;
  var topic2_re = /^topic2\/.*/;

  if (topic.matches(topic1_re)) {
    //topic 1
  } else if (topic.matches(topic2_re)) {
    //topic 2
  }
}

我用一个通用函数解决了这个问题,从 MQTT 订阅模式创建了一个正则表达式。 它实质上用等价的正则表达式替换了 +/#

const sub2regex = (topic) => {
   return new RegExp(`^${topic}$`
       .replaceAll('+', '[^/]*')
       .replace('/#', '(|/.*)')
   )
};

为了演示,在 HiveMQ 上测试:

> let subTopic = 'home/+/light/#';
> let subRegex = sub2regex(subTopic);
> console.log(subRegex.toString()); 
/^home\/[^/]*\/light(|\/.*)$/

> subRegex.test('home/livingroom/light/north');
true
> subRegex.test('home/x/y/light/north');
false

更多结果:

testTrue = [  // These all test true
    'home/kitchen/light/north',
    'home/kitchen/light/fridge/upper', // multiple levels for #
    'home//light/north',  // + matches empty string
    'home/kitchen/light/',  // # matches empty string
    'home/kitchen/light',  // # matches no sub-topic
]
testFalse = [  // These all test false
    'home/x/y/light/north',  // multiple levels for +
    'home/kitchen/temperature',  // not a light
    'gerry/livingroom/light/north',  // not home
]