# MQTT Broker

> 工作站自己的 MQTT Broker：它在通信栏里的那一行、打开和关闭、端口和已连接的设备、客户端认证、它交给 MQTT 驱动的条目“本工作站”，以及它不做的事。

**MQTT Broker** 接收你网络中设备发布的 MQTT 消息，这样试验台或小型实验室不用另装 Broker，就能读取 ESP32 板、网关和传感器。它是“服务器”文件夹的第三行，排在[Modbus 服务器](connector-modbus-server)之后，它不是驱动：设备连到它并发布消息，工作站像读取任何 Broker 一样，通过 [MQTT 驱动](driver-mqtt)读取它们发布的内容。面板在标题下面这样写：“接收你网络中设备发布的 MQTT 消息，设备因此无需自备 Broker。它只接受连接，从不主动连接。”能查看 Connector 的人可以读这一页，能配置 Connector 的人可以修改它。

## 通信栏里的那一行 {#the-row-in-the-column}

这一行位于通信栏树的“服务器”文件夹中，在 Modbus 服务器下面，驱动显示插头的位置上是一个集线器图标。每台工作站正好有一个，它从不被创建，也从不被删除。搜索框按名称找到它，状态筛选项按状态归类：关闭时归入已禁用，端口被占用或无法监听时归入有问题，其余情况归入正常。名称旁边显示 Broker 正在做什么，圆点对此做个概括：

| 这一行显示 | 圆点 | 何时 |
| --- | --- | --- |
| “已关闭” | 灰色 | Broker 已关闭，每台工作站都从这里开始。 |
| “正在端口 1883 上监听”，然后是已连接设备的数量：“没有已连接的客户端”“已连接 1 个客户端”“已连接 3 个客户端” | 绿色 | Broker 已打开且运行时在运行：端口已打开。 |
| “端口 1883 已被占用” | 红色 | Broker 已打开，但另一个程序占用了端口。 |
| “无法在端口 1883 上监听” | 红色 | Broker 已打开，但 Windows 因其他原因拒绝打开端口。 |
| “运行时已停止” | 灰色 | Broker 已打开但运行时已停止：在运行时再次运行之前，端口保持关闭。 |

圆点只属于 Broker：它不计入“驱动”文件夹的汇总，也不计入状态栏，那两处说的是工作站所读取的设备。

## 打开和关闭 {#turning-it-on-and-off}

| 命令 | 作用 | 何时变灰 |
| --- | --- | --- |
| **启用** | 打开 Broker：“打开 Broker：运行时运行期间，它在端口 1883 上监听，MQTT 驱动会获得本工作站读取它所用的条目。”操作记录条显示“MQTT Broker 已打开。” | Broker 已经打开（“Broker 已经打开。”）、有运行记录占用着工作站，或者运行时已停止。 |
| **禁用** | 关闭 Broker：“关闭 Broker：它关闭端口并断开所有客户端。”操作记录条显示“MQTT Broker 已关闭。” | Broker 已经关闭（“Broker 已经关闭。”）、有运行记录占用着工作站，或者运行时已停止。 |

不能配置 Connector 的角色不会被画出这两个命令。是否打开是工作站保存的一项设置，监听则跟随运行时：运行时一启动，Broker 就打开端口；运行时停止时，它关闭端口并断开所有设备；运行时恢复后，它再次打开端口。打不开的端口是 Broker 自己的状态，显示在这一行上和端口字段下方，工作站在没有它的情况下照常运行。

## 端口和客户端卡片 {#the-port-and-clients-card}

| 字段 | 作用 | 取值和默认值 |
| --- | --- | --- |
| **TCP 端口** | Broker 监听的端口，在这台计算机的所有地址上监听，包括 IPv4 和 IPv6，不使用 TLS。在 Broker 监听时修改它，会关闭旧端口、打开新端口，所有设备都会断开；操作记录条显示“MQTT Broker 已移到端口 1884。” | 1 到 65535。默认 1883，即不使用 TLS 的 MQTT 端口。 |
| **已连接的客户端** | 现在连接着多少台设备。只要有设备连接，表格就逐台列出 **客户端 ID**、**客户端地址**（它的 IP 地址和端口）和 **连接时间**。 | 只读。 |

Broker 无法改用的端口，在保存任何内容之前就会被拒绝，原因显示在字段下方，字段回到当前生效的端口：超出范围的数字（“端口必须在 1 到 65535 之间。”），Web 服务器、代理访问、OPC UA 服务器或 [Modbus 服务器](connector-modbus-server)的端口（“端口 N 已经是 Modbus 服务器的端口。请另选一个端口，或者先移动 Modbus 服务器。”），以及被另一个程序占用的端口（“端口 N 在这台计算机上已被占用。请关闭占用它的程序，或者另选一个端口。”）。工作站的其他端口字段也会以同样方式拒绝 Broker 的端口：“端口 N 已经是 MQTT Broker 的端口。请另选一个端口，或者先移动 MQTT Broker。”

卡片下方有一条说明：“不使用 TLS：设备以普通 MQTT 连接，同时最多 100 台。只有 Windows 防火墙放行 TCP 端口 1883 的入站连接，其他计算机才能访问这个 Broker：是否放行由你决定，本工作站从不自行放行。保留消息会保存到工作站重新启动为止。”

同时连接的设备最多 100 台，工作站自己的会话也算在内：再多一台会因超出配额的 MQTT 原因被拒绝，而用自己的客户端 ID 重新连接的设备会拿回原来的位置。保留消息存放在内存中：运行时停止后再启动时它们还在，工作站重新启动后就没有了。

### Windows 防火墙 {#windows-firewall}

工作站从不自行修改 Windows 防火墙。说明下方，一个圆点和一句话说明工作站为 Broker 设置的入站规则是否放行该端口：“端口 1883 上的入站 MQTT 连接对专用网络和域网络放行。”“网络客户端可能被阻止，因为没有本应用拥有的规则放行端口 1883。”，或者在不能管理防火墙的启动方式下，例如隔离的配置文件或不是已安装程序的副本，显示“这种启动方式无法管理 Windows 防火墙。如有需要，请在操作系统中配置入站访问。”只有在规则缺失时，**放行本地网络** 才会在你同意后向 Windows 申请一条名为“Ganter Lab MQTT broker”的规则：该端口的入站 TCP、专用网络和域网络、本地子网、本程序。它要在工作站自己的应用里按下（“防火墙规则只能从工作站本机的桌面应用中应用。”），操作记录条先显示“正在为 MQTT 端口 1883 申请 Windows 防火墙放行…”，再显示“Windows 防火墙现在允许端口 1883 上的 MQTT 连接。”

## 客户端认证 {#client-authentication}

**客户端认证** 卡片决定谁可以连接：

| 选项 | 谁能连接 |
| --- | --- |
| **匿名** | “任何设备都能连接，无论是否提供用户名和密码。”每台工作站都从这里开始。 |
| **用户名和密码** | “所有设备都使用下面这一组用户名和密码登录。”使用其他用户名或密码的设备会被拒绝，诊断日志会记下这件事，并像任何重复的失败一样合并记录。 |

选项下方是 **用户名** 和密码，密码的标签只说明是否已保存密码：**密码（已保存）** 或 **密码（尚未保存）**。已保存的密码从不画回页面：字段一开始是空的，并且“留空就保留已保存的密码。”选项、用户名和密码通过 **套用** 一起生效，在没有任何改动时它是灰色的（“请先更改认证设置再套用。”）；套用后操作记录条显示“MQTT Broker 的认证已保存。”，并且正如按钮旁边那一行所提醒的，“新的认证不再接受的已连接设备会被断开。”

| 输入 | 拒绝时的提示 |
| --- | --- |
| 用户名或密码为空时选择了用户名和密码 | “在 Broker 要求之前，请先输入用户名和密码。” |
| 用户名和密码生效时清空了用户名 | “Broker 要求每台设备提供用户名，因此不能为空。要清除它，请先选择匿名。” |
| 超过 128 个字符的用户名或密码 | “用户名最多 128 个字符。” |

选择匿名时，用户名和密码仍然保存着，留待下次使用。密码的保存方式与工作站所读取 Broker 的密码相同，按这个 Windows 账户加以保护：在另一台计算机或另一个账户上打开的备份不含密码，重新输入之前没有任何设备能登录，卡片会显示“在这个 Windows 账户下无法读取：它只能在输入它的那台计算机和那个 Windows 账户上打开。请在这里重新输入。”

## 本工作站 {#this-station}

面板的最后一张卡片 **本工作站** 说明 Broker 交给 MQTT 驱动的东西：“打开后，Broker 会在 MQTT 驱动下创建条目 本工作站，本工作站通过它读取向这里发布消息的设备：地址为 127.0.0.1，使用 Broker 的端口和认证。请通过扫描或手动在 本工作站 下添加这些设备。关闭 Broker 后，本工作站 及其设备保留原位，处于断开状态。”

| 时机 | 发生的事 |
| --- | --- |
| 打开 Broker 时，工作站还没有这个条目 | MQTT 驱动被添加到工作站，并多出 Broker **本工作站**：127.0.0.1、Broker 的端口、不使用 TLS、已启用；认证为用户名和密码时，带有 Broker 的用户名和密码。 |
| 端口或认证改变时 | 条目随之改变：它的主机、端口和认证变成 Broker 的。名称、客户端 ID、保活时间以及是否启用，仍由你决定。条目自己的面板显示“本工作站通过这个条目读取自己的 MQTT Broker（服务器，MQTT Broker）：它的主机、端口和认证跟随该 Broker，Broker 打开期间它会一直保留。” |
| Broker 打开期间 | 条目不能删除：命令栏、右键菜单和驱动的表格里，**删除 Broker** 保持灰色，并显示“Broker‘本工作站’是本工作站读取自己 MQTT Broker 的途径，因此在该 Broker 打开期间会一直保留。请先在“服务器”下关闭 MQTT Broker。” |
| 关闭 Broker 时 | 条目及其设备留在原处，处于断开状态。这时删除它，下次打开 Broker 时会再次创建。 |

条目下面不会自动添加任何东西：请像在任何 [MQTT 驱动的 Broker](driver-mqtt#the-broker)下一样，通过 Broker 的扫描或手动添加向 Broker 发布消息的设备。Broker 关闭期间，工作站自己的会话会拉长重试间隔，所以打开 Broker 后，条目可能要等最多 30 秒才显示为在线。本工作站也有每个 Broker 都有的[发布卡片](driver-mqtt#the-publish-card)：工作站把自己的数据发布到它自己的 Broker。

## 代理访问 {#agent-access}

| 工具 | 作用 |
| --- | --- |
| `station_broker_status` | 报告 Broker：是否打开、端口、状态、不含密码的认证、已连接的设备以及条目“本工作站”。运行时停止时也能使用。 |
| `station_broker_configure` | 按面板的规则打开或关闭 Broker、改用其他端口、修改认证。 |

这两个名称都不以 `mqtt_broker_` 开头，那是工作站所读取 Broker 的工具；两者都和其他所有工具一起在[工具](agent-tools)中说明。

## 它不做的事 {#what-it-does-not-do}

- 没有 TLS，也没有 WebSocket：设备通过 TCP 以普通 MQTT 连接。
- 所有设备共用一组用户名和密码，从不每台设备各用一组。
- 没有持久会话，保留消息也不会在工作站重新启动后留下。
- 它随工作站一起停止：工作站关闭时仍要继续发布的设备，需要自己的 Broker（[安装一个 Broker](driver-mqtt#installing-a-broker)）。
