Capture Client Connection and Disconnection Event Topic Messages via Data Integration
Client connection and disconnection event topics are system topics used by EMQX to notify changes in client connection status, including $events/client_connected and $events/client_disconnected. Although normal clients cannot subscribe to these topics directly, you can capture them through the Rule Engine for further processing—for example, writing data to a database, forwarding it to other topics, or performing real-time monitoring and analysis.
Because EMQX functions as an MQTT Broker rather than a storage service, and for security and privacy reasons, it does not retain historical client status records or debug-level event logs by default. Therefore, we recommend configuring Data Integration rules for client connection and disconnection event topics in your deployment to enable real-time tracking of device connection status and the preservation of essential activity records, which are valuable for troubleshooting and auditing.
This page introduces the use cases for client connection and disconnection event topics, demonstrates how to capture these messages using the Rule Engine, and uses MQTTX Desktop to simulate a client receiving event topic messages.
Key Use Cases
Client connection and disconnection event topics can be used in multiple scenarios, including:
- Recording device connection history: Log events to an external database to track device connection history and behavior patterns, supporting later analysis and reporting.
- Monitoring device online status and activity: Gain real-time insights into device connectivity and client activity, helping business systems make dynamic adjustments or policy decisions.
- Troubleshooting disconnections: By analyzing the reasons and timing of disconnection events, the technical support team can quickly identify and resolve unexpected disconnections.
- Security auditing and access behavior tracking: Store events in a log platform for access tracking, security investigations, and compliance audits.
Trigger Conditions and Key Fields
Client Connected Event ("$events/client_connected")
- Trigger: Triggered when a client successfully connects.
- Key fields:
| Field | Explanation |
|---|---|
| clientid | The connected client’s ID |
| username | The username used for the connection |
| peername | Client IP address and port |
| keepalive | MQTT keepalive interval (heartbeat frequency from client to broker) |
| clean_start | MQTT clean_start (Whether the client is starting a clean session) |
| expiry_interval | MQTT session expiry interval (how long the session is kept after disconnection) |
| connected_at | Timestamp of when the connection was established (Unit: ms) |
Client Disconnected Event ("$events/client_disconnected")
- Trigger: Triggered when a client disconnects.
- Key fields:
| Field | Explanation |
|---|---|
| reason | Reason for the disconnection |
| clientid | The disconnected client’s ID |
| username | The username used for the connection |
| peername | Client IP address and port |
| disconnected_at | Timestamp of when the client disconnected (Unit: ms) |
TIP
For the full list of event topic fields, refer to the official documentation: Event Topic List
Analysis of Disconnection Scenarios
The reason field in the client disconnected event topic provides the specific cause of a disconnection, which helps in understanding connection issues and optimizing client connection logic. Below is a detailed analysis of all disconnection reasons:
| Reason Code | Explanation |
|---|---|
| normal | The client actively disconnected. This is the standard scenario, where the client ends the session following the normal MQTT protocol flow. |
| kicked | The client was disconnected by the server, usually because an administrator actively terminated the session via the API or console. |
| keepalive_timeout | Triggered when a client fails to send a heartbeat (Pingreq) to EMQX within the specified Keepalive interval. Common causes include: 1. Network jitter: Unstable network between the client and EMQX causes lost, delayed, or dropped heartbeat messages. 2. Client heartbeat issues: The client’s heartbeat mechanism is faulty and does not send MQTT heartbeats within the required interval. For more details, refer to the Keepalive documentation. |
| not_authorized | Triggered when a client fails authentication or lacks sufficient permissions. Common causes include: 1. Authentication failure: The client provides invalid MQTT credentials. 2. Insufficient permissions: When acl_nomatch = disconnect (default), the client attempts a publish/subscribe operation without proper access rights. |
| tcp_closed | The remote side closed the TCP connection. This often occurs when a client crashes or there is a network issue, bypassing the MQTT DISCONNECT packet interaction. Examples include forcibly closing the client application, network interruption by the ISP, or abrupt device network disconnections. |
| internal_error | Occurs due to malformed packets or other unknown errors. Resolving this typically requires inspecting packet contents, checking server logs, or contacting the EMQX technical support team. |
| discarded | Occurs when two clients use the same ClientID with clean_start = true. EMQX discards the existing session, establishes a new session, and disconnects the old client.clean_start = true indicates the client wants a fresh session on each connection. When a new client uses the same ClientID, EMQX treats it as a new session, deletes the old subscriptions and message queues, and replaces the old session with the new connection. |
| takenover | Occurs when two clients use the same ClientID with clean_start = false. EMQX allows the new client to take over the existing session and disconnects the old client.clean_start = false indicates the client wants to reuse the existing session. When a new client connects with the same ClientID, EMQX transfers the old session to the new client while disconnecting the previous client. |
TIP
Below are two common scenarios of ClientID conflict disconnections:
ClientID conflict with repeated session takeover: When multiple different clients use the same ClientID and have automatic reconnection enabled, the new connection repeatedly kicks out the old session, creating a loop of reconnections. In this case, the client’s IP and port often change.
Recommendation: Assign a unique ClientID to each client.
Repeated client reconnections: If a client session still exists but the client does not recognize it as active, the client process may repeatedly send new MQTT CONNECT packets, which can override the existing session. In this scenario, the IP usually remains the same, while the port may change; on some IoT network modules, both IP and port can change.
Recommendation: Review and optimize the client connection logic.
Configure Data Integration to Capture Event Topic Messages
In practice, event topics are typically handled in one of two ways:
- Message republishing: Republishes event topic messages to other MQTT topics. This approach is lightweight, real-time, and fully compatible with the native MQTT ecosystem, making it ideal for quickly consuming and processing events within the system.
- Forwarding to external services: Sends event topic messages to external systems such as databases, message queues, or HTTP services. This approach enables integration with a variety of external systems and supports real-time responses and persistent processing.
This page demonstrates message republishing and forwarding to HTTP services. For other methods, such as forwarding to different databases or external systems, see the official documentation: EMQX Cloud Data Integration.
Message Republish
This section demonstrates how to republish client connection and disconnection event topic messages to other topics.
Create Rule and Action
- In the Data Integration page, under the Data Forward category, click Republish. If you have existing connectors, click New Connector, then select Republish under the Data Forward category.
- Define the Rule SQL in the SQL Editor. To track client disconnection events, you can use the following SQL example:
SELECT
clientid,
username,
reason,
disconnected_at
FROM
"$events/client_disconnected"- Click Next to add an action.
- In the Create Action step, configure the following information:
- Connector: Use the default option Republish.
- Topic: Set the target topic to
client_disconnected. - Payload, QoS, and Retain: Use default values.
- Click Confirm to complete the configuration.
Test Rule and Action
It is recommended to use MQTTX to simulate client connections and message reporting, although any MQTT client can be used.
- Use MQTTX to create two connections to the deployment, with ClientIDs set to
connandsub. - Use client
subto subscribe to the republished topicclient_disconnected. - Disconnect the client
conn. The clientsubshould receive an event message in the following format:
{
"clientid": "conn",
"username": "u_emqx",
"reason": "normal",
"disconnected_at": 1645003578536
}Forward Event Topic Messages to HTTP Services
This section demonstrates how to forward client connection and disconnection event topic messages to an HTTP service. Before you start, you need either a VPC peering connection to access the target connector via its internal IP or a NAT gateway to access it via a public IP.
Create HTTP Server Connector
In the deployment menu, select Data Integration, and under the Web Service category, choose Webhook. If you have existing connectors, click New Connector, then select Webhook under the Web Service category.
In the Create Connector page, fill in the Base URL; other settings can be adjusted as needed.
The URL should point to the HTTP service that will receive the forwarded event messages. The connector will send POST requests to this URL using the payload defined in the rule.
Click Test to verify that EMQX can successfully reach the specified URL.
Click New to complete the connector creation.
Create Rule and Action
- Click New Rule to enter the rule creation page.
- Define the Rule SQL in the SQL Editor. To track client disconnection events, you can use the following SQL example:
SELECT
clientid,
username,
reason,
disconnected_at
FROM
"$events/client_disconnected"- Click Next to start creating the action.
- From the Connector dropdown, select the HTTP Server connector created earlier. Leave the remaining settings as default.
- Click the Confirm button to complete the rule creation.
TIP
For the full process and configuration of forwarding data to an HTTP service, refer to the official documentation: Ingest MQTT Data into HTTP Server.
Test Rule and Action
It is recommended to use MQTTX to simulate client connections and message reporting, although any MQTT client can be used.
- Use MQTTX to connect to the deployment, setting the ClientID to
conn. - Disconnect the client
conn. The HTTP service should receive a POST request, with the request body in the following format:
{
"clientid": "conn",
"username": "u_emqx",
"reason": "normal",
"disconnected_at": 1645003578536
}