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
]
我有来自 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
]