从ESP32 源码学习事件处理函数用法

1、背景

在ESP32中存在很多的回调,并且实现的都比较优美,因此有必要在这方面向她好好学习,向代码开发者致敬。

我下面开始我的胡扯,有问题请大家指出,谢谢。

2、结构

接下去我们学习一下它的逻辑结构以及内含的面向对象的编程思想。(当然这纯属我在写的时候瞎扯的)。

以HTTP数据流为例分析,这个选择是因为目前刚好对这一段熟悉,贪方便而已。

2.1 看看句柄相关的结构体以及初始化

言归正传,看下面一段代码,首先入眼的是定义了一个esp_http_client_config_t 的变量,接下去就利用这个变量初始化HTTP客户端,且返回esp_http_client_handle_t的句柄。

esp_http_client_config_t config = {
			.url = "https://www.ozizz.cn/yyz/device/1/uploadWifi",
			.event_handler = SM_http_event_handler,
			.is_async = true,
			.buffer_size = 1536,
			.timeout_ms = 5000,
	};
	esp_http_client_handle_t client = esp_http_client_init(&config);

在这一段中应该是最能看出代码研发者的编程技能。首先看看esp_http_client_handle_t 这个句柄的结构体的组成

/**
 * HTTP client class
 */
struct esp_http_client {
    int                         redirect_counter;  //重定向次数
    int                         max_redirection_count;  //最大重定向次数
    int                         process_again;      
    struct http_parser          *parser;              //HTTP解析器
    struct http_parser_settings *parser_settings;     //HTTP解析器配置
    esp_transport_list_handle_t     transport_list;    //transport链表
    esp_transport_handle_t          transport;         //要用的transport
    esp_http_data_t                 *request;          //请求数据
    esp_http_data_t                 *response;         //应答数据
    void                        *user_data;            //用户数据
    esp_http_auth_data_t        *auth_data;            //认证数据
    char                        *post_data;          
    char                        *location;             //位置
    char                        *auth_header;          
    char                        *current_header_key;
    char                        *current_header_value;
    int                         post_len;
    connection_info_t           connection_info;      //连接信息
    bool                        is_chunk_complete;    //分块是否完成
    esp_http_state_t            state;                //状态
    http_event_handle_cb        event_handler;        //事件处理函数
    int                         timeout_ms;           //超时
    int                         buffer_size;          //buffer的大小
    bool                        disable_auto_redirect;   //除能自动重定向
    esp_http_client_event_t     event;                  //事件ID
    int                         data_written_index;     
    int                         data_write_left;
    bool                        first_line_prepared;
    int                         header_index;
    bool                        is_async;               //是否阻塞
};

 这些都是变量涵盖了一个HTTP/s客户端在各个阶段时所需要使用的。在实际编程中,将使用到的与客户端操作有关的函数放到这个结构体内,最终形成一个体系。

初始化函数esp_http_client_init就是针对一个结构体对其中的成员变量该分配空间的分配空间,该按配置的赋值的赋值,否则就给一个默认值。

2.2 实际中对该结构体的使用以及触发事件处理的调用

esp_err_t err;
esp_http_client_set_method(client, HTTP_METHOD_POST);
esp_http_client_set_post_field(client, data, len);
while(1)
{
	err = esp_http_client_perform(client);
	if (err != ESP_ERR_HTTP_EAGAIN) {  //非阻塞,直接跳出
		break;
	}
}

事件分派函数如下所示,只要句柄的事件处理函数设置后才有效。

static esp_err_t http_dispatch_event(esp_http_client_t *client, esp_http_client_event_id_t event_id, void *data, int len)
{
    esp_http_client_event_t *event = &client->event;

    if (client->event_handler) {
        event->event_id = event_id;
        event->user_data = client->user_data;
        event->data = data;
        event->data_len = len;
        return client->event_handler(event);
    }
    return ESP_OK;
}
如
http_dispatch_event(client, HTTP_EVENT_ON_DATA, (void *)at, length);

举例来说

event->event_id = HTTP_EVENT_ON_DATA;

event->user_data = client->user_data;

event->data = at;

event->data_len = length;

其中user_data追本溯源

client->user_data = config->user_data; //这是用户数据上下文

3、实践

 

 

 

©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值