Best way - HTTP Response Response parsing

Ritu21
Posts: 123
Joined: Sat Aug 04, 2018 9:58 am

Best way - HTTP Response Response parsing

Postby Ritu21 » Wed Mar 27, 2019 8:37 am

Hi,

I am sending data to http server which returns a response which generates an event HTTP_EVENT_ON_DATA. I need to parse the json response which I am able to do by using flag.
Like I set a flag whenever I am posting data on some url and check that flag in HTTP_EVENT_ON_DATA and accordingly call the parse fuction written by me using cJson library, which obviously parses all the values.

My concern is that there is lot of delay in getting the complete response which make my whole code very slow.

Could you please guide some better way to acheive parsing in less time???

Also, I checked the response time on postman for each url I am using. None of them is above 300ms.From my code I get response after 3000ms which is way higher to digest.

Below is the snippet of code for your understanding:

Code: Select all

esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
    switch(evt->event_id)
	{
        case HTTP_EVENT_ERROR:
            ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
            break;
        case HTTP_EVENT_ON_CONNECTED:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
            break;
        case HTTP_EVENT_HEADER_SENT:
            ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
            break;
        case HTTP_EVENT_ON_HEADER:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
            break;
        case HTTP_EVENT_ON_DATA:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
            if (esp_http_client_is_chunked_response(evt->client)) {
                printf("%.*s", evt->data_len, (char*)evt->data);
		if(g_boolCaptureDeviceInitResponse == true)
		{
			printf("calling Parse_ServerData\n");
			parse_DeviceInit_Response((char*)evt->data);
			g_boolCaptureDeviceInitResponse = false;
		}
	}
	else if (!esp_http_client_is_chunked_response(evt->client)) {
        //Write out data
        printf("%.*s", evt->data_len, (char*)evt->data);
        } 
        break;
        case HTTP_EVENT_ON_FINISH:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
            break;
        case HTTP_EVENT_DISCONNECTED:
            ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED");
            break;
    }
    return ESP_OK;
}

static void device_Init()
{
	g_boolCaptureDeviceInitResponse = true;		
	call_DeviceInit_Api();
	if(bSettings_mode == true){
		printf("...again generating tokens...\n");
		g_boolCaptureGenerateTokenResponse = true;
		generate_Tokens();
	}
}

static void call_DeviceInit_Api()
{
	ESP_LOGI(GTAG,"get server data task started \n");
	char new_initURL[100] = {0};
	bzero(new_initURL, sizeof(new_initURL));
	form_DeviceInitURL(new_initURL);
	esp_http_client_config_t config = {
		.url = new_initURL,
		.event_handler = _http_event_handler,
	};
	printf("Config URL = %s\n", config.url);
	esp_http_client_handle_t client = esp_http_client_init(&config);
	esp_http_client_set_header(client, "Content-Type", "application/json");
	esp_http_client_set_header(client, "Authorization", access_token);
	esp_err_t err = esp_http_client_perform(client);
	if(err == ESP_OK) {
		ESP_LOGI(HTAG, "Get Server Data GET Status = %d, content_length = %d",
				esp_http_client_get_status_code(client),
				esp_http_client_get_content_length(client));
				g_boolDeviceNotInitiated = false;
	} else {
		ESP_LOGE(HTAG, "Get Server Data HTTP GET request failed: %s", esp_err_to_name(err));
		g_boolDeviceNotInitiated = true;
	}
	esp_http_client_cleanup(client);
}

static void parse_DeviceInit_Response(char *monitor)
{
	printf("Data received in parse_DeviceInit_Response\n");
	cJSON *date_time = NULL;
	cJSON *device_group_id = NULL;
	cJSON *enabled = NULL;
	cJSON *settings_mode = NULL;
	cJSON *smart_access = NULL;
	cJSON *missExpToken = NULL;
	cJSON *monitor_json = cJSON_Parse(monitor);
	if (monitor_json == NULL)
	{
		const char *error_ptr = cJSON_GetErrorPtr();
		if (error_ptr != NULL)
		{
			fprintf(stderr, "Error before: %s\n", error_ptr);
		}
	}
	else
	{
		missExpToken = cJSON_GetObjectItem(monitor_json, "errorMessage");
		if(cJSON_IsString(missExpToken) && (missExpToken->valuestring != NULL)){
			strcpy(g_byErrMsg_Buff_ReceivedFromServer, missExpToken->valuestring);
			g_boolErrorReceivedInTokens = true;
			g_boolDeviceInitResponse_ErrorReceived = true; 
		}
		else
		{
			//printf("Data received in monitor_json\n");
			date_time = cJSON_GetObjectItemCaseSensitive(monitor_json, "date_time");
			if (cJSON_IsString(date_time) && (date_time->valuestring != NULL))
			{
				strcpy(g_byTime_DateBuff_ReceivedFromServer, date_time->valuestring);
				enabled = cJSON_GetObjectItem(monitor_json, "enabled");
				if (cJSON_IsTrue(enabled) == 1){
					g_boolEnabledStatus_ReceivedFromServer = enabled->valueint;
				}
				device_group_id = cJSON_GetObjectItemCaseSensitive(monitor_json, "device_group_id");
				if(cJSON_IsString(device_group_id) && (device_group_id->valuestring != NULL))
				{					
					strcpy(g_byDeviceIDBuff_ReceivedFromServer , device_group_id->valuestring);
					int len = strlen(g_byDeviceIDBuff_ReceivedFromServer);
					if((len == 0) && (g_boolEnabledStatus_ReceivedFromServer != 1)){			
						gpio_set_level(SERVER_LED_OUTPUT_PIN, 0);
					}
					else if((len > 1) && (g_boolEnabledStatus_ReceivedFromServer == 1)){
						gpio_set_level(SERVER_LED_OUTPUT_PIN, 1);
					}
				}					
				settings_mode = cJSON_GetObjectItem(monitor_json, "settings_mode");
				if (cJSON_IsTrue(settings_mode) == 1){
					printf("Checking settings_mode \"%d\"\n", settings_mode->valueint);
					bSettings_mode = settings_mode->valueint;
					g_boolSettingsMode_ReceivedFromServer = settings_mode->valueint;
				}
				smart_access = cJSON_GetObjectItem(monitor_json, "smart_access");
				if (cJSON_IsTrue(smart_access) == 1){
					printf("Checking smart_access \"%d\"\n", smart_access->valueint);
					g_boolSmartAccessStatus_ReceivedFromServer = smart_access->valueint;
				}
			}					
			cJSON_Delete(monitor_json);
		}
	}	
}
This is just one api post to http server , similarly there are 7 api either to post or get, all of which gives the response.

If I am clear with the question, looking forward for the response.
If I am not clear, let me know which part is not clear.

Please consider this as very urgent.

Thanks
Ritu.

Ritu21
Posts: 123
Joined: Sat Aug 04, 2018 9:58 am

Re: Best way - HTTP Response Response parsing

Postby Ritu21 » Fri Mar 29, 2019 6:04 am

Waiting for your reply.

jitin17
Posts: 4
Joined: Tue Sep 11, 2018 4:54 am

Re: Best way - HTTP Response Response parsing

Postby jitin17 » Fri Mar 29, 2019 6:53 am

Hi Ritu21,

When you are calling `parse_DeviceInit_Response` on HTTP_EVENT_ON_DATA event, there is a possibility that you won't receive the entire JSON blob, so a better thing to do would be to accumulate entire HTTP body data and then feed it to the `parse_DeviceInit_Response`.

Regarding the delay, can you call this API `esp_wifi_set_ps(WIFI_PS_NONE)` after `esp_wifi_start` in your WiFi setup and let us know if this helps you to reduce the delay.

Ritu21
Posts: 123
Joined: Sat Aug 04, 2018 9:58 am

Re: Best way - HTTP Response Response parsing

Postby Ritu21 » Sat Mar 30, 2019 4:09 am

Hi Jitin,

I used `esp_wifi_set_ps(WIFI_PS_NONE)` api but there is not much difference in delay.

Also, I am getting the complete json blob after which `parse_DeviceInit_Response` is called.

Looking forward for your suggestion on this.

Thanks
Ritu

ESP_Mahavir
Posts: 190
Joined: Wed Jan 24, 2018 6:51 am

Re: Best way - HTTP Response Response parsing

Postby ESP_Mahavir » Mon Apr 01, 2019 12:46 pm

Hi Ritu,

It might be helpful to increase `buffer_size` in http client configuration and check once. (please refer https://github.com/espressif/esp-idf/bl ... ent.h#L117)

Thanks.

Ritu21
Posts: 123
Joined: Sat Aug 04, 2018 9:58 am

Re: Best way - HTTP Response Response parsing

Postby Ritu21 » Tue Apr 02, 2019 6:20 am

Hi,

I m already changing #define DEFAULT_HTTP_BUF_SIZE (512) to #define DEFAULT_HTTP_BUF_SIZE (1536) in the same file you mentioned.
Is is ok or you want me to change the buffer size (as you mentioned) for all http call implicitly??

Thanks.
Ritu

Who is online

Users browsing this forum: No registered users and 95 guests