MQTT 服务端转发
启动内置 MQTT Server,向已连接客户端发布变量、设备、报警和插件事件,并按权限处理变量 RPC 写入和历史读取请求。
转发组范围、触发、分批、缓存和启停见数据转发。本页只说明监听、TLS、客户端限制、Topic、RPC、模板和服务端调试。
功能入口
进入“开发配置 → 数据转发”,按以下顺序配置:
- 保存转发组范围、触发、定时间隔、在线过滤和批处理策略。
- 新增目标,选择“MQTT 服务端转发”,填写目标基本信息。
- 打开“目标属性”,配置监听、安全认证、消息主题、脚本、模板和缓存。
- 保存并启用目标,用测试 MQTT 客户端连接后再打开“目标调试”。
目标基本信息
| 参数 | 默认值 | 如何配置 |
|---|---|---|
| 所属转发组 | - | 必须选择已保存的转发组。 |
| 目标名称 | - | 必填,同组唯一。 |
| 启用 | 开启 | 关闭时不会监听端口。 |
| 日志级别 | Info | 排查监听、认证或发布问题时临时使用 Debug。 |
| 启动超时 | 60 秒 | 页面可填 1~3600 秒。 |
目标属性
监听与安全
| 参数 | 默认值 | 如何配置 |
|---|---|---|
| 连接类型 | Tcp | Tcp 监听 MQTT TCP;WebSocket 通过 HTTP 服务监听 WebSocket。 |
| 端口 | 1883 | TCP 明文常用 1883,TLS 或 WebSocket 端口按部署填写。 |
| WebSocket路径 | /mqtt | 仅 WebSocket 生效,必须以 / 开头。 |
| 启用SSL | 关闭 | 开启后 Listener 使用 TLS。必须选择服务器证书。 |
| 服务器证书名称 | 空 | 从“证书管理”选择带私钥的服务端证书;TLS 开启且证书不存在会启动失败。 |
| CA名称 | 空 | 双向 TLS 时选择用于验证客户端证书的 CA。 |
| 允许不受信任证书 | 关闭 | 关闭时服务端要求并验证客户端证书;外部客户端需携带有效证书和私钥,并满足所配 CA 或系统信任。开启时跳过该校验且不要求客户端证书,仅用于临时实验。 |
| SSL协议版本 | None(系统默认) | 按客户端兼容性或安全策略选择 TLS 版本。 |
| 检查证书吊销 | 关闭 | 按安全策略开启。 |
| 允许连接ID前缀 | 空 | 非空时只接受 Client ID 以该文本开头的客户端;空值允许所有 ID。 |
| 用户名 | 空 | 非空时要求客户端用户名完全匹配。 |
| 密码 | 空 | 与用户名配套,认证失败的客户端会被拒绝。 |
消息与 RPC
| 参数 | 默认值 | 如何配置 |
|---|---|---|
| QoS等级 | 0 | 服务端发布消息使用的 QoS。 |
| 保留消息 | 关闭 | 控制在线 PUBLISH 的 Retain 标志。当前内置服务不保存每主题最后载荷,新订阅者不能据此取得旧值。 |
| RPC写入Topic | RpcWrite | 填主题前缀,不含 +/#;服务端订阅 {前缀}/+,响应为 {前缀}/{请求编号}/Response。 |
| 插件方法RPC Topic | RpcMethod | 固定请求主题,响应加 /Response,不追加编号。留空关闭此连接的方法协议。 |
| 历史读取RPC Topic | RpcHistory | 填不含通配符的主题前缀;请求和分块响应使用请求编号。 |
| 数据请求Topic | 空 | 接收当前结构的快照请求,发布组内已配置模型的快照及对应完成响应;任意文本不是有效请求。 |
| 设备Topic模板 | 空 | 留空不发布设备模型;可使用 ${Name} 等字段。 |
| 变量Topic模板 | TGateway/Variable | 可使用 ${DeviceName}、${Name} 等字段。 |
| 报警Topic模板 | 空 | 留空不发布报警模型。 |
| 插件事件Topic模板 | 空 | 留空不发布插件事件模型。 |
| RPC脚本 | 空 | 选择 MQTT 动态 RPC 脚本处理请求和响应;无需自定义处理时留空。 |
方法协议按被调用设备或目标的“允许方法调用”开关执行,不要求绑定变量,也不配置逐方法白名单。请求禁止 Retain,方法入口不额外设置载荷大小上限;MQTT 协议和服务端报文配置仍生效。主题不能与变量、历史或快照请求及响应重叠。连接身份继续使用本目标的认证,示例和结果处理见插件方法调用。
验证连接与发布
先用一个在线变量、固定变量 Topic 和定时触发完成订阅。外部客户端使用唯一 Client ID 连接,核对服务端列表中的远端地址和身份,再改变现场值,检查同一主题的新变量、质量和时间。
“允许连接ID前缀”匹配 CONNECT 中的客户端 ID,与用户名、设备名和 IP 无关;更改后重新连接验证。用户名密码也在 CONNECT 阶段校验,正确凭据与符合前缀两项都要满足。客户端普通发布只在 Broker 中分发,不会自动改写现场变量。
WebSocket 客户端使用 ws://主机:端口/路径,SSL 开启后使用 wss://...。路径只控制 HTTP 升级入口,不是 MQTT Topic。TLS 服务端需带私钥的服务身份。保持默认关闭“允许不受信任证书”时,还需为客户端证书建立信任,并由客户端出示私钥身份;没有客户端证书的连接会失败。客户端仍需验证服务名称和签发链,MQTT 用户名密码也单独校验。SSL协议版本=None 由系统选择 TLS,并不关闭加密;Default 是旧协议集合,不能当作系统自动选择。开启吊销检查前确保有可用吊销信息。
QoS 以实际发布和订阅共同允许的等级为准。QoS 1 可重复,QoS 2 的协议交付保证也不能扩大为现场写入或数据库业务只执行一次。Retain 在线标志、主题最后值存储和失败缓存分别评估;当前内置服务没有迟订阅保留重放,零字节 Retain 发布也不能被描述为删除了已保存主题。
快照、写入与历史读取
请求当前快照
- 配置专用“数据请求Topic”,客户端先订阅数据 Topic 及完成响应路径。
- 生成唯一的 32 位小写十六进制编号,向数据请求 Topic 发布:
{"Source":"TGateway","RequestId":"6e8c1a7445064ad6b4bb5d5af9cf28b1"}
- 核对组内变量、设备和报警快照,只会发送已经配置的模型。
- 在
数据请求Topic/Response/6e8c1a7445064ad6b4bb5d5af9cf28b1收取{"RequestId":"6e8c1a7445064ad6b4bb5d5af9cf28b1","Success":true}。数据正文与结束标记分别核对。
改变请求 Topic 不会改变变量发布 Topic。使用本次唯一编号和新接收窗口判断结果,不要只从周期消息中找一个相同值。
写入现场变量
向 RPC写入Topic/请求编号 发布按设备名、变量名组织的对象:
{"Demo_Modbus_Device":{"Demo_Modbus_Value":1700}}
在 RPC写入Topic/请求编号/Response 逐变量核对结果,再确认现场回读、采集值及订阅消息一致。关闭目标变量“允许RPC写入”后,同样请求应被拒绝,现场原值保持不变;源变量及设备权限仍然生效。
绑定 MQTT 动态 RPC 脚本时,自定义业务字段由脚本转换,再通过标准写入入口执行。清空脚本恢复默认字典契约;脚本编译存在不表示目标已使用它。完整协议和开发入口见反向写入与 RPC。
读取已有历史
历史请求使用独立前缀,发到 历史读取RPC Topic/请求编号,正文编号必须相同:
{"requestId":"6e8c1a7445064ad6b4bb5d5af9cf28b1","operation":"targets","responseChunkBytes":4096,"input":null}
响应位于 历史读取RPC Topic/请求编号/Response。检查成功状态,按 chunkIndex 收齐 chunkCount 块,各块 Base64 解码后顺序拼接,再 gzip 解压并解析 JSON。targets 返回空列表也可能是有效结果,它只表示当前没有可查询 provider。
先创建历史存储并形成两个不同样本,再枚举稳定目标名,使用 numberRecords 查询分页或 series 的 Raw 序列,填写真实变量 ID 与 UTC 时间窗口。上传分片、响应字节分块和历史查询分页是三个不同参数;原始序列与聚合查询也应分别核对。
目标变量属性
| 参数 | 默认值 | 说明 |
|---|---|---|
| 允许RPC写入 | 开启 | 允许外部 MQTT 客户端通过当前目标写入该变量。监控点应关闭。 |
变量必须已在转发组范围内;新增目标变量属性不会把变量加入转发组。
该插件还继承通用 数据1~数据10 预留文本字段,默认为空,不会自动进入消息;需要由实体脚本读取并输出,再参与模板。
消息、模板与缓存
数据与脚本
继承属性包括“详细日志”“JSON缩进格式化”“JSON忽略Null”、设备/变量/报警/插件事件列表和字典上传、四类实体脚本,以及“上传模板配置”。这些开关的配置方式见MQTT 客户端转发;服务端与客户端使用相同的消息实体和 ${字段名} 占位符。
默认变量字典叶子是完整实体;Text 模板产生字符串叶子,Json 模板的叶子类型由模板决定。忽略 Null 控制默认实体的空属性,不会删除模板显式生成的 null,也不删除 0、false 或空字符串。列表关闭但保留正文模板时,要核对单条 JSON 字符串外层。实体脚本只改上传对象,不改变现场源值。完整组合见上传模型与模板。
上传模板字段
在“上传模板配置”中选择 Text 或 JSON 模式并插入 ${字段名},保存前先执行预览。
| 数据类型 | 可用字段 |
|---|---|
| 变量 | Id、Name、DeviceName、Value、RawValue、LastSetValue、CollectGroup、CollectTime、CreateTime、ChangeTime、IsOnline、DataType、Unit、RegisterAddress、OtherMethod、Description、ProtectType、RpcWriteEnable、Remark1~Remark5、ValueInited、IsMemory |
| 设备 | Id、Name、ActiveTime、DeviceStatus、PluginName、Description、LastErrorMessage、Remark1~Remark5 |
| 报警 | AlarmId、VariableId、Name、DeviceName、AlarmCode、AlarmLevel、AlarmLimit、AlarmText、RecoveryCode、AlarmTime、EventTime、FinishTime、ConfirmTime、ConfirmText、AlarmType、EventType、Remark1~Remark5 |
| 插件事件 | DeviceName、ObjectValue |
缓存与容量
| 参数 | 默认值 | 如何配置 |
|---|---|---|
| 启用失败重试缓存 | 开启 | 发送失败时保留待发数据,恢复后自动补发。 |
| 缓存文件最大行数 | 262144 | CacheDB 出站上限,超过后删除最旧数据。 |
| 上传分片大小 | 2000 | 变化记录的缓存读取批量上限;完整周期快照可保留组批次边界,不能据此推算每条消息的点数。 |
| 内存队列上限 | 100000 | 达到上限后先转入 CacheDB;落盘失败保留已接收记录并拒绝新记录,由上游重试。 |
| 过滤离线数据 | 关闭 | 开启后过滤离线变量,转发组在线过滤也会生效。 |
| 并发上传数量 | 1 | 服务端共享连接向多个客户端发布,先保持 1,确认负载后再调整。 |
没有订阅客户端时服务端仍可能成功发布,因此客户端断开不等于发送失败,也不会自动形成每客户端离线邮箱。缓存只在真实失败及配置保留条件下补发;使用离线期间不同旧值验证,不能只看服务在线。容量按缓存模型分别限制,增加上限不能找回已经淘汰的数据。验证步骤见离线缓存与补传。
目标调试
进入“开发配置 → 数据转发”,选择 MQTT 服务端目标,打开“调试 → 协议调试 · MqttServer”。
| 功能 | 作用 |
|---|---|
| 服务端状态 | 查看监听状态、已连接客户端、订阅和消息活动。 |
| 发布消息 | 填写测试 Topic 和正文,验证服务端发布。 |
| 客户端管理 | 查看或断开指定客户端连接。 |
服务端调试

发布消息

状态监控

断开客户端会立即中断其连接,执行前必须确认客户端身份和影响范围。
手工发布使用输入的 Topic、UTF-8 原文、QoS 和 Retain,独立客户端应收到唯一标记,现场变量保持原值。客户端和主题列表分别有搜索、排序及分页;搜索不会建立或删除订阅,主题订阅数也不是累计发布次数。踢出只关闭当前会话,不修改账号和 ID 前缀,允许的客户端仍可重新连接。
验证方法
- 启用目标,确认 Listener 已启动。
- 使用允许的 Client ID 和凭据连接测试 MQTT 客户端。
- 订阅变量 Topic,让一个转发范围内的测试变量产生新值。
- 核对 Topic、正文、QoS、Retain 和消息条数。
- 需要 RPC 时,再单独核对请求 Topic、响应 Topic 和变量权限。
常见问题
| 现象 | 检查方法 |
|---|---|
| 客户端无法连接 | 端口、连接类型、防火墙、TLS 证书、凭据和 Client ID 前缀。 |
| 订阅端没有消息 | 转发组范围、目标状态、Topic 模板、QoS、客户端订阅和目标日志。 |
| 新订阅者没有取得旧值 | 当前内置服务不保存主题最后载荷;使用结构化快照请求获取当前组内数据,并核对完成响应。 |
| RPC 写入失败 | RPC Topic、目标变量权限、请求正文、响应 Topic 和源变量写权限。 |
| 模板正文无效 | 模板预览、占位符、JSON 语法和 ${字段名} 对应实体。 |