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。
    • Payload、QoS 和 Retain: 使用默认值。
  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
}