基于官方 webclient 的 http client

发布于 2020-01-05 16:20:36    浏览:820

该库简单的封装了官方的 webclient API (并未对文件的请求API进行封装,原因是这个API需要过多的内存)
创建该库的原因是因为官方的 webclient API 均是阻塞型的,会造成线程高延迟 (例如我的线程是屏幕的刷新)

该库提供以下 API

异步操作API:

/* --------------------------   Asynchronous API   -------------------------- */
int http_get(const char *url, http_result_cb_t cb);
int http_post(const char *url, const char *data, http_result_cb_t cb);
int http_send(const char *url, const char *type, const char *data, http_result_cb_t cb);
/* --------------------------   Asynchronous API   -------------------------- */

异步API是创建了一个线程去执行的这个请求的,请求成功并且有数据返回的时候,才会调用回调函数(前提是你有提供回调函数)
例如:

char *ad_text;
char *ad_text_color;
void get_text_result_cb(char *buf, uint16_t len)
{
    printf("len:%d<br>%s<br>", strlen(buf), buf);
    cJSON *json = cJSON_Parse(buf);
    cJSON *cotent = cJSON_GetObjectItem(json, "content");
    cJSON *color = cJSON_GetObjectItem(json, "color");
    char *content_str = cJSON_GetStringValue(cotent);
    char *color_str = cJSON_GetStringValue(color);
    printf("<br>content:%s<br>color:#%lx<br>", content_str, color_str);
    if (content_str)
    {
        if (ad_text)
            cJSON_free(ad_text);
        ad_text = content_str;
    }
    if (color_str)
    {
        if (ad_text_color)
            cJSON_free(ad_text_color);
        ad_text_color = color_str;
    }
    //  #是作为颜色的结束标志,详细可以查看littlevGL官网文档
    lv_label_set_text_fmt(label2, "%s %s#", ad_text_color, ad_text);
}
void get_text(void)
{
    http_get("http://" URL ":" PORT "/ad?cmd=get", get_text_result_cb);
}

阻塞型的API:

/* --------------------------   synchronous API    -------------------------- */
char* http_get_sync(const char *url);
char* http_post_sync(const char *url, const char *data);
char* http_sync(const char *url, const char *type, const char *data);
/* --------------------------   synchronous API    -------------------------- */

阻塞型API 是封装了官方的 webclient 的过程,请求成功并且有数据返回的会把返回一个缓冲区给你(这些API会申请与返回内容一样大的内存空间去存储它)
使用完之后记得要释放掉这个缓冲区,不然会造成内存溢出的哟。

并提供了一个低内存消耗的文件请求API:

char http_get_file(const char *url, const char *path, http_get_file_cb_t cb);

例如:

extern void Jpeg_Dec_file(const char *path);
#define IMAGE_FILE_NAME "image.jpeg"
void get_image_cb(void)
{
    Jpeg_Dec_file(IMAGE_FILE_NAME); //  解析jpeg文件并刷新到屏幕
}
static void get_image(void)
{
    http_get_file("http://" URL ":" PORT "/ad?cmd=get_image", "/" IMAGE_FILE_NAME, get_image_cb);
}

倘若你系统中没有挂载存储就不要使用这个 API 啦

以下是两个回调函数的定义:

typedef void (*http_result_cb_t)(char *buf, uint16_t len);
typedef void (*http_get_file_cb_t)(void);

以下是库文件,欢迎大家测试。
大家记得用完之后反馈下问题和使用感受哟。
http_client.h
http_client.c

上面两个例子展示:

 \ | /
- RT -     Thread Operating System
 / | \     4.0.3 build Jan  5 2020
 2006 - 2019 Copyright by rt-thread team
[D/drv.sram] sram init success, mapped at 0x68000000, size is 1048576 bytes, data width is 16
[SFUD] Find a Winbond flash chip. Size is 16777216 bytes.
[SFUD] W25Q128 flash device is initialize success.
[I/sal.skt] Socket Abstraction Layer initialize success.
LCD ID:1963
[I/at.clnt] AT client(V1.3.0) on device uart3 initialize success.
msh />[I/at.dev.esp] esp0 device wifi is connected.
[I/at.dev.esp] esp0 device network initialize successfully.
[E/at.clnt] execute command (AT+CIPDNS_CUR?) failed!
[W/at.dev.esp] please check and update esp0 device firmware to support the "AT+CIPDNS_CUR?" cmd.
[E/at.clnt] execute command (AT+CIPDNS_CUR?) failed!
[W/at.dev.esp] please check and update esp0 device firmware to support the "AT+CIPDNS_CUR?" cmd.
last:0        Now:1578206928
len:253
{"content":"iu这些覅u上的覅速度和反思u发货是到付还是地方和但是fish的方式的好的放声大哭积分回馈圣诞节放假是东方航空技术的回复收到反馈说的的回复卡死的回复技术的开发","color":"#8080ff"}

content:iu这些覅u上的覅速度和反思u发货是到付还是地方和但是fish的方式的好的放声大哭积分回馈圣诞节放假是东方航空技术的回复收到反馈说的的回复卡死的回复技术的开发
color:#2001bad0
[I/http.get.file] This file size is : 19.61Kb.

0%
3%
6%
10%
13%
16%
20%
23%
26%
30%
33%
36%
40%
43%
46%
50%
53%
56%
60%
63%
66%
70%
73%
76%
80%
83%
86%
90%
93%
96%
OK

b1839a4f7dcf2da9cff7745e2499950.jpg

查看更多

4 个回答
14510690
14510690 2020-01-07
This guy hasn't written anything yet
:)不错,学习了
昂头向前走
昂头向前走 2020-01-07
This guy hasn't written anything yet
14510690 发表于 2020-1-7 09:26
不错,学习了


谢谢给个评价哈,兄弟
14510690
14510690 2020-01-08
This guy hasn't written anything yet
但是目前的API好像POST还不支持二进制数据传输吧,好像要自己实现了
昂头向前走
昂头向前走 2020-02-13
This guy hasn't written anything yet
    本帖最后由 昂头向前走 于 2020-2-13 21:55 编辑


14510690 发表于 2020-1-8 09:17
但是目前的API好像POST还不支持二进制数据传输吧,好像要自己实现了

不应该的吧,毕竟我都可以接收图片了。二进制的数据直接在接收数据的内容中,上传的话具体我也不清楚,我没有用到POST二进制数据到服务器,没有研究过这个问题,也没有仔细的去研究官方的代码是否支持二进制数据上传。

我的理解是,这个http请求返回的内容无论是二进制还是文本,我们读取的时候都是按uint8进行读取,也就是一个字符。那么我们处理的时候,究竟是把这数据当作是二进制内容还是文本内容都是自己决定的,如果你是自己提供服务的话,服务端也是一样的道理。

如果你POST了一个二进制数据,你可以看下服务端接收到的http消息头是否有二进制标志





14510690
14510690 2020-06-16
This guy hasn't written anything yet
我看已经更新了,2020.13.31支持二进制了,更新版本V2.2.0,但是官网显示还是V2.1.2哦,希望官方尽快同步显示版本吧!同时发现一个问题。v2.0.0 正常,我猜测是url中有":"会引起错误。202,希望官方更新一下,解决一下这个BUG,因为老版本正常的。
14510690
14510690 2020-06-17
This guy hasn't written anything yet
再跟一下贴,吐槽一下哦,我发现webclient的webclient_read支持Transfer-Encoding: chunked ,但是webclient_write不支持,希望官方能够改进一下。毕竟HTTPClientWriteData支持chunk的。

撰写答案

请登录后再发布答案,点击登录
关注者
0
被浏览
820

发布
问题

分享
好友

手机
浏览

扫码手机浏览