主题和最佳实践 - MQTT核心系列:第五章

主题和最佳实践 - MQTT核心系列:第五章

作者:HiveMQ Team

翻译:索隆有几把刀

欢迎来到MQTT核心系列的第五章。这个系列一共有十章,用来介绍MQTT的核心特性和概念。在这一章中,我们聚焦于主题和最佳实践。正如我们前面已经提到的,MQTT代理通过使用消息的主题来决定消息该发送给谁。我们还将看看SYS-topics,这是一种特殊的主题,他将揭示代理本身的信息。

主题

在MQTT中,主题指一个由UTF-8编码的字符串,代理会用它来为每一个连接的客户端过滤消息。一个主题会由一个或多个主题层级组成。每个主题等级由一个正下划线分割。

主题

相较于消息队列,MQTT主题是非常轻量级的。客户端不需要在它们推送或者订阅某个主题前先创建它。代理会接受每一个有效的主题,而不需要事先初始化。

下面是一些主题的举例:

myhome/groundfloor/livingroom/temperature
USA/California/San Francisco/Silicon Valley
5ff4a2ce-e485-40f4-826c-b1a5d81be9b6/status
Germany/Bavaria/car/2382340923453/latitude

注意,每一个主题都必须含有至少一个字符,且主题字符串允许空格。主题是大小写敏感的。例如,myhome/temperature和MyHome/Temperature是两个不同的主题。另外,正斜杆本身也是一个有效的主题。

单层:+

如名称所示,一个单层通配符取代一个主题层级。加号在主题里面代表一个单层的通配符。

单层

除了通配符,单层通配符能匹配主题中的任意字符串。例如,订阅myhome/groupfloor/+/temperature会有如下结果:
单层匹配结果

多层:#

多层通配符会适配多个主题层级。#在主题里代表多层的通配符。为了使代理能够确定匹配哪些主题,必须将多级通配符放置为主题中的最后一个字符,并在其前面加上正斜杠。
多层匹配结果
当客户端使用多级通配符订阅主题时,无论主题有多长或多深,客户端都会接收到以通配符前的模式开头的主题的所有消息。如果你仅仅只用井号,那么你会收到代理的所有消息。如果希望获得高吞吐量,则仅使用多级通配符进行订阅是一种反模式(请参见下面的最佳实践)。

用$开始的主题

通常,你可以根据你的需求命名你的主题。但是有一个例外,以 开 头 的 主 题 具 有 不 同 的 用 途 。 当 您 将 多 级 通 配 符 作 为 主 题 ( # ) 订 阅 时 , 这 些 主 题 不 属 于 订 阅 。   开头的主题具有不同的用途。当您将多级通配符作为主题(#)订阅时,这些主题不属于订阅。   符号主题保留用于MQTT代理的内部统计。客户不能将消息发布到这些主题。 符 号 主 题 保 留 用 于 M Q T T 代 理 的 内 部 统 计 。 客 户 不 能 将 消 息 发 布 到 这 些 主 题 。 目 前 , 此 类 主 题 尚 无 官 方 标 准 化 。 通 常 , 符号主题保留用于MQTT代理的内部统计。客户不能将消息发布到这些主题。目前,此类主题尚无官方标准化。通常, MQTT SYS /用于以下所有信息,但是代理实现会有所不同。关于$ SYS-topics的一项建议是在MQTT GitHub Wiki中。这里有些例子

$SYS/broker/clients/connected

$SYS/broker/clients/disconnected

$SYS/broker/clients/total

$SYS/broker/uptime

总结

上面就是MQTT消息主题的基础。如你所见,MQTT主题是动态的,并提供了极大的灵活性。当你在实际应用中使用通配符时,有一些问题需要你注意的。我们已经在之前的工作中收集了一些最佳实践,并且我们总是这些实践进行讨论。

最佳实践

切勿使用前导正斜杠

在MQTT中正斜杠是允许的。例如,/myhome/groundfloor/livingroom。但是,前导斜杠引入了不必要的主题级别,其前面的字符为零。零不会带来任何好处,并且经常导致混乱。

切勿在主题中使用空格

空格是每一个程序员的天敌。当事情进展不如预期时,空格会让阅读和调试主题变得更加困难。就像前导正斜线一样,不能因为它被允许,就去使用它。在UTF-8中有很多种不同的空格类型,这样不常见的字符应该避免使用。

保持主题简短

每个消息中都会包含主题。你应该让你的主题将可能的简短。对于小型机,每一个字节都很重要,因此主题长度有很大影响。

只使用ASCII编码,避免字符无法打印

因为非ASCII UTF-8编码的字符经常会导致显示错误,找到字符集相关的错误是非常困难的。除非无法避免,我们建议您不要这么做。

给主题嵌入一个唯一标识符或者客户端id

在主题中放入一个能唯一标志客户端的标识符是非常有好处的。这个唯一标识符能帮助你确认这条小时是谁发的。这个嵌入的id能用于强制授权。只有这个客户端id拥有与主题相同的id的时候,这个客户端才被允许推送消息。例如,一个id为client1的客户端允许推送消息到主题client1/status,但是不被允许推送消息到client2/status。

不要订阅#

有时候,订阅发送给代理的所有消息是很很有必要的。例如,我们需要把所有消息都存储到数据库。但是不要用#和一个客户端去订阅代理的所有消息,因为在通常情况下,一个客户读是无法处理这么大的负载的(尤其是在巨大吞吐量的情况下)。我们的建议是实现代理的拓展。

不要忘记了可拓展性

虽然主题是一个可伸缩的内容,预分配空间是没有必要的。但是,主题任然值得订阅者和发布者仔细斟酌。我们应该思考主题怎样能容纳新的功能而不必改变整个主题的层级结构。

用明确的主题,不要用通用的

不要用命名队列的方式来命名主题。当你命名主题时,它们应该尽可能的不同。例如,你有三个不同的室内设备,你因该创建三个不同的主题,myhome/livingroom/temprature,myhome/livingroom/brightness和myhome/livingroom/humidity,而不是统一用myhome/livingroom。用单一的主题来应付所有的消息是不可取的。明确的命名能帮助你更好的使用MQTT的其它特性,如保存消息。更多的细节,请看这个系列的第8章。


以上就是第五章的内容了。感谢您的阅读,在下一章,我们将介绍MQTT的服务质量。我们将解释为什么它是MQTT的核心特性,并且你将学会如何使用它。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值