espressif / esp-aws-iot

AWS IoT SDK for ESP32 based chipsets
Apache License 2.0
256 stars 154 forks source link

How to check the connection status with aws (CA-268) #163

Open arslan437 opened 1 year ago

arslan437 commented 1 year ago

here is my code snippet.

How can I check if the device is still connected to aws or not.

void aws_iot_main(void *pvParameters)
{
    int returnStatus = EXIT_SUCCESS;
    MQTTContext_t mqttContext = { 0 };
    NetworkContext_t xNetworkContext = { 0 };
    bool clientSessionPresent = false, brokerSessionPresent = false;
    struct timespec tp;

    /* Seed pseudo random number generator (provided by ISO C standard library) for
     * use by retry utils library when retrying failed network operations. */

    /* Get current time to seed pseudo random number generator. */
    ( void ) clock_gettime( CLOCK_REALTIME, &tp );
    /* Seed pseudo random number generator with nanoseconds. */
    srand( tp.tv_nsec );

    /* Initialize MQTT library. Initialization of the MQTT library needs to be
     * done only once in this demo. */
    returnStatus = initializeMqtt( &mqttContext, &xNetworkContext );

    if( returnStatus == EXIT_FAILURE )
    {
        LogError("Failed initialize MQTT");
        return;
    }

    /* Attempt to connect to the MQTT broker. If connection fails, retry after
    * a timeout. Timeout value will be exponentially increased till the maximum
    * attempts are reached or maximum timeout value is reached. The function
    * returns EXIT_FAILURE if the TCP connection cannot be established to
    * broker after configured number of attempts. */
    returnStatus = connectToServerWithBackoffRetries( &xNetworkContext, &mqttContext, &clientSessionPresent, &brokerSessionPresent );

    if( returnStatus == EXIT_FAILURE )
    {
        LogError("Failed to connect to MQTT broker");
        return;
    }

    clientSessionPresent = true;

    returnStatus = subscribeToTopic( &mqttContext );

    if( returnStatus == EXIT_FAILURE )
    {
        LogError("unable to subscribe to topics");
        return;
    }

    returnStatus = publishToTopic( &mqttContext, PUB_TOPIC_BOOT, "Booting up...", MQTTQoS0);

    if( returnStatus == EXIT_FAILURE )
    {
        LogError("unable to publish the boot message");
        return;
    }

    for ( ; ; )
    {
        if( brokerSessionPresent == true )
        {
            // LogInfo( ( "An MQTT session with broker is re-established. "
            //             "Resending unacked publishes." ) );

            /* Handle all the resend of publish messages. */
            returnStatus = handlePublishResend( &mqttContext );
        }
        else
        {
            // LogInfo( ( "A clean MQTT connection is established."
            //             " Cleaning up all the stored outgoing publishes.\n\n" ) );

            /* Clean up the outgoing publishes waiting for ack as this new
                * connection doesn't re-establish an existing session. */
            cleanupOutgoingPublishes();
        }
        MQTT_ProcessLoop( &mqttContext );
        // sleep( MQTT_SUBPUB_LOOP_DELAY_SECONDS );
        vTaskDelay(50 / portTICK_PERIOD_MS);
    }
}
avsheth commented 1 year ago

Hi @arslan437 MQTT_ProcessLoop and receiveSingleIteration would essentially manage keep-alive at MQTT layer. It would send MQTT Ping request every keepAliveSeconds (set to MQTT_KEEP_ALIVE_INTERVAL_SECONDS in the application) and waits for CONFIG_MQTT_PINGRESP_TIMEOUT_MS for the response.

If the response isn't received within the set time,MQTT_ProcessLoop would return error.

arslan437 commented 1 year ago

Is the library have a dedicated function for that ?

Lets say internet is limited or for some reason esp32 can access the internet.

How can I check if library is still connected with the aws?

espressing commented 4 weeks ago

Warming this up as is extremely vital for many, including our, application, too - and nothing moved since start of 2023 on such crucial aspect. At the moment it seems it is virtually impossible to realise that network (at any layer) has gone away and handle disconnect/reconnect when MQTT session has to be alive "permanently" - instead of creating connection then demolishing everything as examples do. Even if one propagates up the MQTT status from e.g. publish to topic calls, it is rather opaque - some status codes like receive failed don't say much about underlying reason - therefore, one might try re-establishing MQTT session from transport link upward... but... how.