aws / aws-iot-device-sdk-embedded-C

SDK for connecting to AWS IoT from a device using embedded C.
MIT License
975 stars 623 forks source link

Why happend MQTTKeepAliveTimeout and DUPLICATE_CLIENTID #1816

Closed willyting closed 1 year ago

willyting commented 1 year ago

HI all

I found a log with "dt_signaller_process MQTT_ProcessLoop returned with status = MQTTKeepAliveTimeout" at the same time. Why the error happened?

In our process, we will reconnect after this error. We guess it trigger the DUPLICATE_CLIENTID disconnect. I found this error disconnect form iot log "AWSIotLogsV2" in CloudWatch.

Is it mean the old connection was fine at that time? What is the recommend action for this error?

paulbartell commented 1 year ago

@willyting , MQTTKeepAliveTimeout is returned when the amount of time since the last received packet exceeds the keep alive time configured when calling MQTT_Connect.

Calling MQTT_ProcessLoop should trigger an MQTT_Ping if needed to keep the connection alive. You must call MQTT_ProcessLoop frequently enough that coreMQTT can meet the timeout value specified in the pConnectInfo->keepAliveSecond field.

You may need to modify the MQTT_PINGRESP_TIMEOUT_MS or PACKET_RX_TIMEOUT_MS configuration items depending on the typical latency of your connection. The best reference for these configuration items is core_mqtt_config_defaults.h.

DUPLICATE_CLIENTID is triggered when a client reconnects without gracefully disconnecting (via a call to MQTT_Disconnect ).

willyting commented 1 year ago

Thank you, @paulbartell So the interval of calling MQTT_ProcessLoop() should small then MQTT_PINGRESP_TIMEOUT_MS, right? We will refine our calling mechanism of MQTT_ProcessLoop()

paulbartell commented 1 year ago

@willyting: It should be less than the configured keepAliveSecond timeout, Ideally significantly more frequently so that incoming messages can be processed in a timely manner.

The receiveSingleIteration function called by MQTT_ProcessLoop handles all messages in the receive buffer before checking for a ping response timeout. From inspecting the code, calling MQTT_ProcessLoop at least as often as MQTT_PINGRESP_TIMEOUT_MS is not strictly necessary but would improve responsiveness.

This periodic ping functionality is included in coreMQTT because the MQTT spec allows the server to disconnect a client after 1.5 x the keepAliveSecond value specified in the CONNECT packet. This value can be safely increased in most cases, but do take into account any NAT timeouts on your network if applicable.

Alternatively, you may call MQTT_ReceiveLoop instead of MQTT_ProcessLoop to handle incoming messages and periodically calling MQTT_Ping from your application to ensure that the required keep alive interval is met.

I'm going to close this issue, but feel free to reopen it if you have further questions on this topic.