跳到正文

MQTT ​

MQTT 界面是一个 MQTT 客户端,用于查看代理并更改其中的内容。连接后,默认会订阅 #:代理保存的每个主题都会连同其最新值构成一棵树。在此之上,您可以发布、清除保留值、把主题保存为信号,或把它变成实验中的一个步骤。

Signal Lab 使用明文 TCP 上的 MQTT 3.1.1,订阅、发布和遗嘱都支持 QoS 0、1 和 2。不支持 MQTT 5,也不支持 TLS:只接受 mqtts:// 或 MQTT 5 客户端的代理无法连接。

连接 ​

  1. 打开 MQTT。
  2. 填写 代理主机 和 端口。
  3. 除非代理要求特定的客户端 ID,否则保持 客户端 ID 不变。仅在代理要求时添加 用户名 和 密码。
  4. 按 连接。

连接会先打开 TCP 连接并完成 MQTT 握手,然后才做其他事,因此密码错误或端口关闭会当场报告。连接期间连接字段会锁定;断开连接 会关闭它。该连接是控制台任务条中的一个任务,也可以在那里停止。

字段内容默认值
代理主机代理的 IP 地址或主机名127.0.0.1
端口代理的端口1883
客户端 ID您的客户端在代理处的名称。不能为空,且在那里必须唯一:第二个使用相同 id 的客户端会把第一个挤下线。signal-lab- 加六个随机十六进制数字,每次启动应用都会更新
用户名、密码仅在代理需要时发送——由于没有 TLS,以明文发送。只有密码而没有用户名时根本不会发送:MQTT 3.1.1 无法单独携带密码。空
保活间隔(s)连接可以保持静默的秒数。Signal Lab 每隔其一半时间向代理发送一次 ping;客户端静默达到该值的 1.5 倍时,代理会将其断开。0 表示关闭 ping。60
清除会话开启:每次连接都不带已存储的订阅和已排队的消息。关闭则会请求代理为这个客户端 ID 在两次连接之间保留它们。开启
连接时扫描 及其 QoS连接一建立就订阅的过滤器;# 表示所有主题。留空:不订阅。#,QoS 0
断线时代为发布一条消息向代理提供一份遗嘱(见下文)关闭

代理有 6 秒时间来接受 TCP 连接,另有 6 秒来应答握手。

遗嘱 ​

遗嘱是代理为您保存的消息,如果您的连接在没有正常告别的情况下断开,代理会自行发布它。在线状态通常就是这样实现的:设备向自己的状态主题发布 online,而它的遗嘱把同一主题设为 off。

勾选 断线时代为发布一条消息 后,设置 发布到 和 发布内容(默认为 off)。遗嘱以 QoS 2 发布,并保留。没有主题时,不发送遗嘱。

订阅 ​

扫描过滤器会在连接时订阅。要订阅更多:

  1. 在 添加过滤器 中,输入一个主题过滤器。
  2. 选择它的 QoS。
  3. 按 订阅 或 Enter。

过滤器是带通配符的主题:

通配符表示示例
+恰好一级sensors/+/state 匹配 sensors/door/state
#其下所有层级,只能是最后一个字符sensors/# 匹配 sensors/door/state 和 sensors

订阅 列出每个过滤器以及代理授予的结果:qos0、qos1 或 qos2——代理授予的等级可能低于您请求的——或 已拒绝。取消订阅 取消订阅其中一个。

QoS投递
0至多一次:发送后即遗忘
1至少一次:会得到确认,可能到达两次
2恰好一次:两步握手;重投不会显示两次

主题树 ​

到达的每条消息都会进入 主题,即由主题各层级构成的树。主题会显示其最新值、值被保留时显示 R,以及收到多条消息时的消息条数。点击某一层即可展开或折叠它。

  • 在上方的字段中输入内容,即可只列出路径或最新值包含该文本的主题。
  • 树的上方显示主题数量、其中有多少保留了值,以及连接期间您正在监听的代理。
  • 载荷以文本显示;不是 UTF-8 的字节显示为替换字符。
  • 清除 会清空这棵树。没有其他操作会清空它:切换界面或断开连接时它都保持原样,直到应用关闭。

消息以每秒十批的方式到达界面。当代理在十分之一秒内发送超过 4000 条消息时,该批中最早的那些不会进入树,并在树的上方计为“未显示”。

主题面板 ​

选择一个带值的主题,即可在树的下方看到它:值、QoS、retain、字节、消息 和 最后出现。它的按钮:

按钮作用
载入发布把主题、值、QoS 和保留标志复制到 发布
等待此消息向打开的实验添加一个等待 MQTT步骤:主题为此主题,代理为此代理,任意载荷,2000 ms 超时
清除保留值移除保留值(见下文)
保存为信号把该主题及其最新值作为信号保存到 已捕获 文件夹

发布 ​

  1. 连接。
  2. 在 发布 下,输入 主题 和 载荷。
  3. 选择 QoS,如果代理应把这条消息作为该主题的值、提供给之后订阅的每个客户端,请勾选 retain。
  4. 按 发布。

控制台会确认每次发布:QoS 0 立即确认,QoS 1 和 2 则在代理确认后确认。用于发布的主题不含通配符,也不能为空:含 + 或 # 的主题会在发送任何内容之前被拒绝,并给出与信号、步骤和 signallab send mqtt 相同的消息,连接保持原样。只有订阅接受带通配符的过滤器。

清除保留值 ​

保留值会一直留在代理上,直到被替换;每个订阅的客户端都会先收到它——过期的保留值是设备启动后进入错误状态的典型原因。移除它的唯一方式是发布一个带保留标志的空载荷。

主题面板中的 清除保留值 会这样做:按下它,然后按 确定清除?。它会在您的连接上以 QoS 1 发布空的保留载荷。仅在已连接且该主题的最新值被保留时可用。您也可以手动完成:载荷 留空,并勾选 retain。

WARNING

清除会同时改变所有客户端看到的代理内容。

在检查器中 ​

捕获开启时,MQTT 流量会以协议 mqtt 出现:

来源内容数量
mqtt界面连接发布的内容;空的保留发布判定为 clears retained每一条
mqtt连接收到的消息每 200 ms 至多一条
mqtt-send自带连接的发布:界面未连接到信号所属代理时触发的信号、步骤、signallab send mqtt(判定 one-shot)每一条
experiment-wait等待 MQTT 步骤的订阅收到的消息,不含重放的保留值每一条

摘要读作 topic = payload,适用时还带有 QoS 和 retained。参见检查器。

保存与复用 ​

  • 保存为信号。 发布 下的 保存… 会把代理(连接的 代理主机 和 端口)、主题、载荷、QoS 和保留标志保存到信号库;在发布面板中按 Ctrl+S 效果相同,并在面板与该信号关联后更新它。参见信号。
  • 触发 MQTT 信号。 当此界面连接到信号所指的代理时(主机相同,不区分大小写,端口也相同;信号未给出端口时为 1883),从库中触发的信号会经由该连接发出,并使用其客户端 ID 和凭据。否则——未连接,或连接到其他代理——它会向自己的代理打开一个属于自己的连接——全新的客户端 ID,没有用户名——发布,等待其 QoS 所要求的确认,然后断开。名称不做解析,因此 localhost 和 127.0.0.1 算作不同的代理。库中不保存密码。
  • 在实验中。 保存的 MQTT 信号可以在实验的 添加节点 菜单中 已保存的信号 下列出,选中即可成为 MQTT 发布 步骤。

在实验中 ​

步骤作用
MQTT 发布连接、发布一条消息并断开——不使用用户名或密码,干净会话,15 秒内完成。详情
等待 MQTT运行开始时订阅,等待某个主题过滤器上载荷匹配的消息;订阅时重放的保留值会被忽略。详情
模拟器本次运行自己的 MQTT 代理。详情

这两个步骤都不登录,因此需要一个接受无用户名客户端的代理。

代理模拟器 ​

Signal Lab 也可以充当代理:MQTT 代理 模拟器把客户端发布的内容路由给已订阅者——3.1.1、明文 TCP、QoS 0、1 和 2、保留消息、遗嘱、可选登录——并像设备一样按规则应答。把您的设备和此界面指向它,即可在没有真实代理的情况下测试。参见模拟器。

从命令行 ​

signallab send mqtt 用属于自己的连接发布一条消息:

bash
signallab send mqtt 127.0.0.1:1883 lab/light/1/set on --qos 1
signallab send mqtt 127.0.0.1:1883 lab/light/1/state "" --retain
text
✔ lab/light/1/set → 127.0.0.1:1883 · 2 B · qos1

第二行清除一个保留值。未给出端口时,代理位于 1883。它不使用凭据。代理接收了消息时退出码为 0,无法连接或拒绝时退出码为 1。参见命令行。

问题 ​

您看到的内容常见原因
… refused the connection — nothing is listening on that port该地址和端口上没有代理。
… accepted the connection but did not answer in time — is it an MQTT broker?那里有程序在监听,但它不使用 MQTT,或者通过 TLS 使用。
… answered with something other than MQTT 3.1.1不是 MQTT 代理,或代理发来了 Signal Lab 无法读取的内容。
… does not accept MQTT 3.1.1 clients该代理只接受 MQTT 5。
… rejected the client ID — choose another one该 ID 太长,或含有代理不接受的字符。
… rejected the username or password凭据错误,或只有密码而没有用户名。
… did not authorize this client — check its access rules代理的访问规则拒绝这个客户端。
… is unavailable right now — try again later代理在线,但不接受客户端。
Enter a client ID — brokers refuse an empty one客户端 ID 为空。
A publish topic cannot contain the wildcards + or #要发布到的主题含有 + 或 #。它们用于订阅;发布时一次只能针对一个主题。
某个过滤器显示 已拒绝代理的访问规则禁止它,或过滤器格式错误(# 不在最后,+ 与其他字符共用一级)。
连接后不久就断开另一个客户端使用了相同的 客户端 ID 进行连接。
树中不出现任何内容扫描过滤器为空,或代理不让这个客户端看到任何内容。

每条错误信息都列在错误信息中。