使用数据集成获取连接确认事件主题消息
连接确认事件主题 $events/client_connack 会在服务端向客户端发送 CONNACK 报文时触发。reason_code 字段可用于判定连接是否成功,并指示失败的具体原因,为排查客户端连接失败问题提供了重要线索。虽然普通客户端无法直接订阅该主题,但可以通过规则引擎捕获事件消息,用于写入数据库、转发至其他主题或执行实时监控与分析等后续处理。
由于 EMQX Broker 作为 MQTT Broker 而非存储服务,并受安全隐私限制,默认不会保存客户端的历史状态记录或调试级别事件日志信息。因此,建议在部署中使用连接确认事件主题配置数据集成规则,以实时掌握设备连接情况并保留必要的行为记录,这对于后续的问题排查和审计分析都具有重要意义。
本页将介绍连接确认事件主题的使用场景,演示如何通过规则引擎捕获事件主题消息并进行处理,并使用 MQTTX Desktop 模拟客户端接收事件主题消息。
应用场景
连接确认事件主题可用于多种场景,包括:
- 排查连接失败原因:捕获并记录客户端连接失败的
reason_code和相关信息,帮助快速定位问题来源。 - 监控设备接入质量:实时掌握客户端的连接尝试情况,识别频繁连接失败的设备或区域,从而优化接入配置、网络条件或鉴权策略。
- 安全审计与访问追踪:记录连接确认事件中的客户端信息至外部平台,为安全审计与合规分析提供数据支撑。
触发条件与关键字段
连接确认事件 ("$events/client_connack")
- 触发条件:服务端向客户端发送 CONNACK 报文时触发。
- 关键字段:
| 字段 | 解释 |
|---|---|
| reason_code | 各种原因代码 |
| clientid | 成功连接的 Client ID |
| username | 成功连接的用户名 |
| peername | 客户端连接的 IP 地址和端口 |
| keepalive | MQTT 保活间隔 (客户端向 Broker 定期发送心跳消息的时间间隔) |
| clean_start | MQTT clean_start (客户端是否复用已存在的会话) |
| expiry_interval | MQTT Session 过期时间 (客户端会话在断开连接后应保留的最长时间) |
| timestamp | timestamp - 事件触发的时间戳 (单位:毫秒) |
TIP
连接确认事件主题的完整字段信息,请参阅官方文档:客户端事件。
连接失败场景分析
连接确认事件主题中的 reason_code 字段提供了连接错误的具体原因,有助于深入理解连接问题并优化客户端连接逻辑。reason_code 字段在 MQTT v3.1.1 中定义了以下原因码:
| 原因码 | 解释 |
|---|---|
| connection_accepted | 客户端已成功连接到服务端。 |
| unacceptable_protocol_version | 服务端不支持客户端请求的 MQTT 协议。通常发生在客户端使用了与服务端不支持的协议版本,或者客户端指定了一个错误的协议版本或协议名。 |
| client_identifier_not_valid | 客户端提供的 ID 虽然符合 UTF-8 编码规范,但服务端不允许。例如设置 Clean Start 为 0 但 Client ID 为空,或 Client ID 超出服务端允许的长度限制。 |
| server_unavailable | 网络连接已建立,但服务端暂时不可用。这可能是由于系统负载过高,或当前服务端认证服务异常等等。 |
| malformed_username_or_password | 客户端提供的用户名或密码格式不正确,导致认证失败。常见问题包括非法字符、编码错误或字段缺失。 |
| unauthorized_client | 客户端未获得连接权限。可能是认证信息无效,或客户端尝试进行未授权的操作,被服务端拒绝。 |
在 MQTT 5.0 中, reason_code 的种类大幅增加,使客户端能够更精确地识别和定位连接失败的具体原因。常见原因码包括:
| 原因码 | 解释 |
|---|---|
| success | 连接成功,客户端已被服务端接受。 |
| unspecified_error | 未指定的错误,表示某一方不希望向另一方透露错误的具体原因,或者协议规范中没有能够匹配当前情况的原因码。 |
| malformed_packet | 客户端发送的连接报文格式错误,例如字段缺失或编码不符合协议规范。 |
| protocol_error | 协议使用不当,客户端发送了违反 MQTT 协议规范的请求。常见情况包括在同一连接内发送多个 CONNECT 报文、报文中重复属性,或属性值不合法。 |
| implementation_specific_error | 报文有效,但当前服务端的实现不接受该报文,导致连接被拒绝。 |
| unacceptable_protocol_version | 服务端不支持客户端请求的 MQTT 协议。通常发生在客户端使用了与服务端不支持的协议版本,或者客户端指定了一个错误的协议版本或协议名。 |
| client_identifier_not_valid | 客户端提供的 ID 虽然符合 UTF-8 编码规范,但服务端不允许。设置 Clean Start 为 0 但 Client ID 为空,或 Client ID 超出服务端允许的长度限制。 |
| bad_username_or_password | 客户端使用了错误的用户名或密码,将被拒绝连接。 |
| not_authorized | 客户端未获得授权,通常是因为没有匹配到对应的用户名。 |
| server_unavailable | 网络连接已建立,但服务端暂时不可用。这可能是由于系统负载过高,或当前服务端认证服务异常等等。 |
| server_busy | 服务端繁忙,无法处理新的连接请求,请稍后再试。 |
| banned | 客户端被禁止连接,可能由于异常连接行为被列入黑名单,或被管理员手动封禁。 |
| bad_authentication_method | 客户端使用了服务端不支持的认证方法,或在重新认证时更改了认证方式。 |
| topic_name_invalid | 主题名的格式正确,但是不被客户端或服务端接受。 |
| packet_too_large | 报文超过客户端或服务端允许的最大长度。例如在 CONNECT 报文中设置了过大的遗嘱消息。 |
| quota_exceeded | 客户端的连接数量超出服务端的限额。 |
| retain_not_supported | 服务端不支持保留消息,但客户端在连接时将遗嘱消息设置为保留消息。 |
| qos_not_supported | 服务端不支持客户端请求的 QoS 等级。例如 CONNECT 报文中的遗嘱消息设置了超出服务器允许的 QoS 等级。 |
| use_another_server | 服务端告知客户端应该临时切换到另一个服务端。 |
| server_moved | 服务器迁移,服务端告知客户端应该永久切换到另一个服务端。 |
| connection_rate_exceeded | 客户端连接速率超出服务端限制,通常由于频繁重连或异常连接行为导致。 |
配置数据集成获取事件主题消息
在实际使用中,事件主题通常有以下两种处理方式:
- 消息重发布:将事件主题消息重新发布到其他 MQTT 主题。这种方式轻量、实时性强,并且与 MQTT 原生生态兼容,适合在系统内部快速消费和处理事件。
- 转发至外部服务:将事件主题消息发送至外部系统,如数据库、消息队列或 HTTP 服务。该方式支持与各种外部系统集成,便于实现实时响应和持久化处理。
本页仅演示消息重发布和转发至 HTTP 服务的方法,其他转发至不同数据库或外部服务的方式可参考官方文档:EMQX Cloud 数据集成。
消息重发布
本节将演示如何将连接确认事件主题消息重新发布至其他主题。
创建规则和动作
- 在数据集成页面中的数据转发服务分类下点击消息重新发布。如果已经创建过其他的连接器,则点击新建连接器,然后在数据转发 服务分类下选择消息重新发布。
- 在 SQL 编辑器 中定义规则 SQL。如需排查客户端连接失败事件,可参考以下 SQL 示例:
SELECT
clientid,
username,
reason_code,
timestamp
FROM
"$events/client_connack"- 点击下一步,添加动作。
- 在创建动作步骤页中,配置以下信息:
- 使用连接器:使用默认选项
消息重新发布。 - 主题:设置目标主题为
client_connack。 - Payload、QoS 和 Retain: 使用默认值。
- 使用连接器:使用默认选项
- 点击确定完成配置。
测试规则和动作
推荐使用 MQTTX 模拟客户端连接与消息上报,同时您也可以使用其他任意客户端完成。
- 使用 MQTTX 创建一个连接到部署,将 ClientID 设置为
sub。 - 使用客户端
sub订阅接收重发布消息的主题client_connack。 - 再创建一个连接
conn到部署,此时客户端sub应该能收到以下格式的事件主题消息:
{
"clientid": "conn",
"username": "u_emqx",
"reason_code": "success",
"timestamp": 1645003578856
}转发事件主题消息至 HTTP 服务
本节将演示如何将连接确认事件主题消息转发至 HTTP 服务。开始之前,您需要创建 VPC 对等连接以通过内部网络 IP 访问目标连接器。或者开通 NAT 网关,通过公网 IP 访问目标连接器。
创建 HTTP Server 连接器
- 在部署菜单中选择数据集成,在 Web 服务分类下选择 HTTP 服务。如果已经创建过其他连接器,选择新建连接器,然后在 Web 服务分类下选择 HTTP 服务。
- 在创建连接器页面中填写 URL,其他配置项可按需调整。URL 应指向将接收事件消息的目标 HTTP 服务。连接器会按照规则中定义的 payload 向该 URL 发送 POST 请求。
- 点击测试按钮测试连接,如果 HTTP 服务能够正常访问,则会返回成功提示。
- 点击新建按钮完成配置。
创建规则和动作
- 点击新建规则进入新建规则步骤页。
- 在 SQL 编辑器中定义规则 SQL。如需排查客户端断连事件,可参考以下 SQL 示例:
SELECT
clientid,
username,
reason_code,
timestamp
FROM
"$events/client_connack"点击下一步开始创建动作。
从使用连接器下拉框中选择之前创建的 HTTP Server 连接器。剩下的配置保持默认值。
点击确认按钮完成规则创建。
TIP
关于将数据转发至 HTTP 服务的完整流程与配置,可参考官方文档:将 MQTT 数据发送到 HTTP 服务。
测试规则和动作
推荐使用 MQTTX 模拟客户端连接与消息上报,同时您也可以使用其他任意客户端完成。
- 使用 MQTTX 连接到部署,将 ClientID 设置为
conn。 - 此时 HTTP 服务应该能收到 POST 请求,请求体原始内容的格式为:
{
"clientid": "conn",
"username": "u_emqx",
"reason_code": "success",
"timestamp": 1645003578856
}