Skip to content

使用数据集成获取连接确认事件主题消息

连接确认事件主题 $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 地址和端口
keepaliveMQTT 保活间隔 (客户端向 Broker 定期发送心跳消息的时间间隔)
clean_startMQTT clean_start (客户端是否复用已存在的会话)
expiry_intervalMQTT Session 过期时间 (客户端会话在断开连接后应保留的最长时间)
timestamptimestamp - 事件触发的时间戳 (单位:毫秒)

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客户端连接速率超出服务端限制,通常由于频繁重连或异常连接行为导致。

配置数据集成获取事件主题消息

在实际使用中,事件主题通常有以下两种处理方式:

  1. 消息重发布:将事件主题消息重新发布到其他 MQTT 主题。这种方式轻量、实时性强,并且与 MQTT 原生生态兼容,适合在系统内部快速消费和处理事件。
  2. 转发至外部服务:将事件主题消息发送至外部系统,如数据库、消息队列或 HTTP 服务。该方式支持与各种外部系统集成,便于实现实时响应和持久化处理。

本页仅演示消息重发布和转发至 HTTP 服务的方法,其他转发至不同数据库或外部服务的方式可参考官方文档:EMQX Cloud 数据集成

消息重发布

本节将演示如何将连接确认事件主题消息重新发布至其他主题。

创建规则和动作

  1. 数据集成页面中的数据转发服务分类下点击消息重新发布。如果已经创建过其他的连接器,则点击新建连接器,然后在数据转发 服务分类下选择消息重新发布
  2. SQL 编辑器 中定义规则 SQL。如需排查客户端连接失败事件,可参考以下 SQL 示例:
SQL
SELECT
    clientid,
    username,
    reason_code,
    timestamp
FROM
    "$events/client_connack"
  1. 点击下一步,添加动作。
  2. 创建动作步骤页中,配置以下信息:
    • 使用连接器:使用默认选项消息重新发布
    • 主题:设置目标主题为 client_connack
    • PayloadQoSRetain: 使用默认值。
  3. 点击确定完成配置。

测试规则和动作

推荐使用 MQTTX 模拟客户端连接与消息上报,同时您也可以使用其他任意客户端完成。

  1. 使用 MQTTX 创建一个连接到部署,将 ClientID 设置为 sub
  2. 使用客户端 sub 订阅接收重发布消息的主题 client_connack
  3. 再创建一个连接 conn 到部署,此时客户端 sub 应该能收到以下格式的事件主题消息:
json
{
    "clientid": "conn",
    "username": "u_emqx",
    "reason_code": "success",
    "timestamp": 1645003578856
}

转发事件主题消息至 HTTP 服务

本节将演示如何将连接确认事件主题消息转发至 HTTP 服务。开始之前,您需要创建 VPC 对等连接以通过内部网络 IP 访问目标连接器。或者开通 NAT 网关,通过公网 IP 访问目标连接器。

创建 HTTP Server 连接器

  1. 在部署菜单中选择数据集成,在 Web 服务分类下选择 HTTP 服务。如果已经创建过其他连接器,选择新建连接器,然后在 Web 服务分类下选择 HTTP 服务
  2. 创建连接器页面中填写 URL,其他配置项可按需调整。URL 应指向将接收事件消息的目标 HTTP 服务。连接器会按照规则中定义的 payload 向该 URL 发送 POST 请求。
  3. 点击测试按钮测试连接,如果 HTTP 服务能够正常访问,则会返回成功提示。
  4. 点击新建按钮完成配置。

创建规则和动作

  1. 点击新建规则进入新建规则步骤页。
  2. SQL 编辑器中定义规则 SQL。如需排查客户端断连事件,可参考以下 SQL 示例:
sql
SELECT
    clientid,
    username,
    reason_code,
    timestamp
FROM
    "$events/client_connack"
  1. 点击下一步开始创建动作。

  2. 使用连接器下拉框中选择之前创建的 HTTP Server 连接器。剩下的配置保持默认值。

  3. 点击确认按钮完成规则创建。

TIP

关于将数据转发至 HTTP 服务的完整流程与配置,可参考官方文档:将 MQTT 数据发送到 HTTP 服务

测试规则和动作

推荐使用 MQTTX 模拟客户端连接与消息上报,同时您也可以使用其他任意客户端完成。

  1. 使用 MQTTX 连接到部署,将 ClientID 设置为 conn
  2. 此时 HTTP 服务应该能收到 POST 请求,请求体原始内容的格式为:
json
{
    "clientid": "conn",
    "username": "u_emqx",
    "reason_code": "success",
    "timestamp": 1645003578856
}