MQTT杂记

文章目录

本文记录一些学些MQTT的过程中的重点和难点,学习材料包括:

角色

mqtt-publish-subscribe

  • MQTT Broker - 消息代理服务器
  • MQTT Client - 消息发布者,通过QoS和Topic发布和订阅消息。MQTT Client可以同时是Publisher和Subscriber

订阅

  • 包含一个主题和QoS
  • 订阅与单个会话关联,一个会话可以包含一个或者多个订阅

主题名和主题过滤器

以下内容多来自MQTT3.1.1规范

MQTT Client通过主题发布和订阅消息。主题名可以有不同层级,通过/划分。主题可能是管理员在服务端预先定义好的,也可能是服务端收到第一个订阅或使用那个主题名的应用消息时动态添加 的。主题过滤器通过在主题名中引入通配符来匹配一个或者多个主题。

注意:MQTT允许使用主题过滤器进行订阅(匹配)多个主题,但是不允许通过主题过滤器进行发布

主题语义和用法

主题名和主题过滤器必须符合下列规则:

  • 所有的主题名和主题过滤器必须至少包含一个字符
  • 主题名和主题过滤器是区分大小写的
  • 主题名和主题过滤器可以包含空格
  • 主题名或主题过滤器以前置或后置斜杠"/"区分
  • 只包含斜杠"/"的主题名或主题过滤器是合法的
  • 主题名和主题过滤器不能包含空字符 (Unicode U+0000)
  • 主题名和主题过滤器是 UTF-8 编码字符串,它们不能超过 65535字节

例如:

  • "ACCOUNTS"和"Accounts"是不同的主题名
  • "Accounts payable"是合法的主题名
  • "/finance" 和 "finance"是不同的

多层通配符#

# 用于匹配主题中的任意层级的通配符。多层通配符必须是主题过滤器的最后一个字符,用于匹配它的父级和任意数量的子层级。例如,"sport/tennis/player1/#" 匹配下列主题名:

  • "sport/tennis/player1"
  • "sport/tennis/player1/ranking"
  • "sport/tennis/player1/score/wimbledon"

一些其他的例子:

  • "sport/#"也匹配单独的 "sport" ,因为"#" 包括它的父级
  • "sport/tennis/#"也是有效的
  • "sport/tennis#"是无效的
  • "sport/tennis/#/ranking"是无效的

单层通配符+

在主题过滤器的任意层级都可以使用单层通配符,包括第一个和最后一个层级。它占据的是主题过滤器的整个层级,匹配的是特定的某个层级,不能匹配子层级。例如,对于主题过滤器"sport/tennis/+":

  • "sport/tennis/player1" - 匹配
  • "sport/tennis/player2" - 匹配
  • "sport/tennis/player1/ranking" - 不匹配

一些其他的例子:

  • "sport/+"不匹配 "sport"但是却匹配 "sport/"
  • "+"是有效的
  • "+/tennis/#"是有效的
  • "sport+"是无效的
  • "sport/+/player1"也是有效的
  • "/finance"匹配 "+/+"和 "/+",但是不匹配"+"

$开头的主题

服务端不能将"$"字符开头的主题名和"#/+"开头的主题过滤器匹配。"$"字符开头的主题名应该用于其他目的

  • "$SYS/ "被广泛用作包含服务器特定信息或控制接口的主题的前缀
  • 应用不能使用 "$" 字符开头的主题 (也就是MQTT Client用于交互业务数据的主题)
  • 订阅 "#"的客户端不会收到任何发布到以"$"开头主题的消息
  • 订阅 "+/monitor/Clients" 的客户端不会收到任何发布到" $SYS/monitor/Clients"的消息
  • 订阅 "$SYS/#"的客户端会收到发布到以"$SYS/"开头主题的消息
  • 订阅 "$SYS/monitor/+"的客户端会收到发布到"$SYS/monitor/Clients"主题的消息
  • 如果客户端想同时接受以" $SYS/"开头主题的消息和不以"$" 开头主题的消息,它需要同时 订阅"#"和"$SYS/#"