把MQTT订阅过滤器写成一个#,容易被口头解释成“所有主题都能收到”。但OASIS的MQTT 3.1.1标准在介绍通配符之后,另列Topics beginning with $一节,明确限制了以$开头的主题名。这条边界需要和通配符定义一起阅读。[1]

第4.7.1节先区分主题名与主题过滤器:订阅过滤器可以使用通配符,主题名本身不能使用这些通配符。多层通配符#表示父层及任意数量的子层,并且需要单独出现或跟在主题层级分隔符后,处于过滤器最后。它的能力描述的是层级匹配,并没有消除后续对主题起始字符的约束。

第4.7.2节的规范要求编号为MQTT-4.7.2-1。它要求服务器不能把以#或+通配符开头的主题过滤器,与以$开头的主题名相匹配。于是,单独的#虽然表示很宽的层级范围,仍不会匹配这一类主题;问题不在于$后面还有多少层,而在于过滤器和主题的开头属于该条款限定的组合。

紧接着的非规范性说明用具体名称解释结果:订阅#不会收到发布到$开头主题的消息;订阅$SYS/#则对应以$SYS/为前缀的主题。标准还用$SYS/monitor/+与$SYS/monitor/Clients展示显式前缀下的单层匹配。这些例子帮助理解边界,不能反过来把$SYS/等同于所有以$起始的名称。

该节另说明,$SYS/已被广泛用作包含服务器特定信息或控制接口的主题前缀。这里是对常用前缀的解释,而非对某个实际代理一定产生哪些主题的保证。即使过滤器在语义上能够匹配,也不能据此虚构服务已经提供消息、客户端已订阅成功或数据已经送达。

标准的例子把普通主题与$SYS/主题的接收范围分开表达。这有助于纠正“多层通配符等于完全没有边界”的理解,却不构成一份应当直接用于生产的订阅配置方案。具体账户、代理实现与业务授权没有进入本稿证据范围,文章也没有连接任何设备或发送测试消息。

再往后的第4.7.3节还提到,服务器可能使用安全组件选择性地授权客户端对主题资源的操作。匹配规则与授权状态因而不能被混写。本文的资料分析是:一份记录若只保留过滤器文字,就不足以认定某个实际客户端应当收到什么;它首先能说明的是按本版标准怎样理解这个过滤器。

本稿采用2014年10月29日OASIS Standard版本,实际阅读已采集文本的版本页及第4.7节相关文字,不声称读完全部标准。提取文本存在部分字符编码异常,且在120000字符处截断;本稿只采用显示清楚的规则编号、字符和完整句子,没有重新提取或改换来源。该日期是标准版本日期,未作为当前HTML首发日期,来源日期留空。

信息来源

本文基于上述公开资料整理,未使用来源页面的图片、视频或嵌入媒体。