multiple requests timeout with http client

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
agmi_3321141
Level 4
Level 4
5 likes given First like received First like given

Hello!

I am using the HTTP client library to make 3 different requests. One request is posted continuously. The second and third is sent every minute sequentially (through flags), like: 0 -> 1 -> 2. The same connection sends different requests.

I use the keep alive header to keep the connection open. Due to some configurations on the sever, I get disconnected roughly every minute so I use a flag to call the http_client_disconnect() and http_request_deinit() APIs and I'm back in business. However I have noticed that sometimes, after a while say 30-40minutes (this is just an estimate) later my requests start bombing. I start getting semaphore timeouts on all of them and things never recover. I am not entirely sure how to debug this problem. I'm not sure if it is related to how I re-initialize my requests. What is the right way to re-initialize the request/connection after getting a disconnect callback? Such a callback might be received while processing any of the 3 requests. My 2nd request is a housekeeping request that is a long json and the 3rd is a http bulk request which can get huge if my queue size gets bigger, so they have a higher semaphore timeout.

I have provided a snippet of what I'm trying, hope someone can give me some hints to debug this!

// 1 min timer

static void housekeeping_callback(void *arg)

{

    send_packet_type = 1;

}

static void http_send_thread( uint32_t arg )

{

    wiced_result_t result;

    WPRINT_APP_INFO (( "Started httpservice_thread\n" ));

    do

    {

        /*wait for network up*/

        wiced_rtos_delay_milliseconds( 100 );

    } while ( wiced_network_is_ip_up( WICED_STA_INTERFACE ) != WICED_TRUE );

    while ( 1 )

    {

        /* check for network link */

        if ( wiced_network_is_ip_up( WICED_STA_INTERFACE ) != WICED_TRUE )

        {

            wiced_rtos_delay_milliseconds( 100 );

            continue;

        }

        switch (send_packet_type) {

            case 0:

            {

                wiced_rtos_pop_from_queue( &whttp_queue, &pop, WICED_NEVER_TIMEOUT );

                send_packet();

            }

            break;

            case 1:

                send_housekeeping_packet();

                send_packet_type = 2;

            break;

            case 2:

            {

                int count = get_queue_size();

                char *bulk_packet = (char *)malloc(sizeof ( (count) * sizeof(buffer) ) );

                for (int i = 0; i < count; i++) {

                    wiced_rtos_pop_from_queue( &whttp_queue, &pop, 200 );

                }

                send_bulk_packet();

                free(bulk_packet);

                send_packet_type = 0;

            }

            break;

            default:

            break;

        }

    }

}

// requests 1 and 2 follow same pattern!

// static void send_housekeeping_packet()

// static void send_bulk_packet()

static void send_packet()

{

    wiced_result_t result;

        if (got_disconnected) {

            http_request_deinit( &requests[0] );

            http_client_disconnect( &client );

            wiced_rtos_delay_milliseconds( 50 );

            got_disconnected = WICED_FALSE;

        }

    if ( wiced_network_is_ip_up( WICED_STA_INTERFACE ) == WICED_TRUE && is_connected_http == WICED_FALSE) {

        // configure HTTP client parameters

    client_configuration.flag = (http_client_configuration_flags_t)(HTTP_CLIENT_CONFIG_FLAG_SERVER_NAME | HTTP_CLIENT_CONFIG_FLAG_MAX_FRAGMENT_LEN);

    client_configuration.server_name = (uint8_t*) SERVER_HOST;

    client_configuration.max_fragment_length = TLS_FRAGMENT_LENGTH_1024;

    http_client_configure(&client, &client_configuration);

    WPRINT_APP_DEBUG( ( "Connecting to %s\n", SERVER_HOST ) );

    // if you set hostname, library will make sure subject name in the server certificate is matching with host name you are trying to connect. pass NULL if you don't want to enable this check

    client.peer_cn = (uint8_t*) SERVER_HOST;

        if ( ( result = http_client_connect( &client, (const wiced_ip_address_t*)&ip_address, SERVER_PORT, HTTP_NO_SECURITY, CONNECT_TIMEOUT_MS ) ) != WICED_SUCCESS )

        {

            WPRINT_APP_INFO( ( "Error: failed to connect to server: %u\n", result) );

            return;

        } else {

            is_connected_http = WICED_TRUE;

        }

    }

    WPRINT_APP_DEBUG( ( "Connected\n" ) );

    jsonize_packet(send_packet_buffer);

    header[0].field        = HTTP_HEADER_HOST;

    header[0].field_length = sizeof( HTTP_HEADER_HOST ) - 1;

    header[0].value        = SERVER_HOST;

    header[0].value_length = sizeof( SERVER_HOST ) - 1;

    #define JSON_URL "application/json"

    header[1].field        = HTTP_HEADER_CONTENT_TYPE;

    header[1].field_length = sizeof( HTTP_HEADER_CONTENT_TYPE ) - 1;

    header[1].value        = JSON_URL;

    header[1].value_length = sizeof( JSON_URL ) - 1;

    #define CONNECTION "Keep-Alive"

    header[3].field        = HTTP_HEADER_CONNECTION;

    header[3].field_length = sizeof( HTTP_HEADER_CONNECTION ) - 1;

    header[3].value        = CONNECTION;

    header[3].value_length = sizeof(CONNECTION) - 1;

    char messageLengthBuffer[10]; // Enough to hold the characters for the Content-Length: header

    sprintf(messageLengthBuffer," %d",strlen(send_packet_buffer)); // Put the message body into the buffer so that you can strlen it

    header[2].field        = HTTP_HEADER_CONTENT_LENGTH;

    header[2].field_length = sizeof( HTTP_HEADER_CONTENT_LENGTH ) - 1;

    header[2].value        = messageLengthBuffer;

    header[2].value_length = strlen(messageLengthBuffer);

    wiced_time_get_time(&start_send_time);

    http_request_init( &requests[0], &client, HTTP_POST, request_uris[0], HTTP_1_1 );

    http_request_write_header( &requests[0], &header[0], 4 );

    http_request_write_end_header( &requests[0] );

    http_request_write( &requests[0], (uint8_t*)send_packet_buffer, strlen(send_packet_buffer) );

    result = http_request_flush( &requests[0] );

    if ( result != WICED_SUCCESS )

    {

        WPRINT_APP_INFO( (" POST request flush failed\n") );

    }

    else

    {

        result = wiced_rtos_get_semaphore(&requestSemaphore,7000);

        if ( result != WICED_SUCCESS )

            WPRINT_APP_DEBUG( (" POST request timed out \n") );

        else

        {

            WPRINT_APP_DEBUG( ("\nPOST successful\n") );

        }

    }

}

static void event_handler( http_client_t* client, http_event_t event, http_response_t* response )

{

    switch( event )

    {

        case HTTP_CONNECTED:

            break;

        case HTTP_DISCONNECTED:

        {

            got_disconnected = WICED_TRUE;

            is_connected_http = WICED_FALSE;

            break;

        }

        case HTTP_DATA_RECEIVED:

        {

            // set semaphore

            wiced_rtos_set_semaphore(&requestSemaphore);

        break;

        }

        default:

        break;

    }

}

0 Likes
1 Solution
GauravS_31
Moderator
Moderator
Moderator
10 questions asked 250 solutions authored 250 sign-ins

Disable the second and third HTTP requests and check if the problem is still present with just one continuous request. This will help to isolate the cause of the issue.

View solution in original post

1 Reply
GauravS_31
Moderator
Moderator
Moderator
10 questions asked 250 solutions authored 250 sign-ins

Disable the second and third HTTP requests and check if the problem is still present with just one continuous request. This will help to isolate the cause of the issue.