AliOS Things 3.0应用笔记:http client简单应用

简介: AliOS Things 3.0版本新增加了httpc组件(http 客户端组件),httpc组件支持多种RESTful的API调用,包括GET、POST、PUT、HEAD等,也支持https安全协议。
+关注继续查看

image.png

给AliOS Things一颗STAR(前往GitHub关注我们)


目录

简介

AliOS Things 3.0版本于9月27日在云栖大会正式发布,在新版本中带来了全新的应用开发框架,帮助用户快速构建自己的应用。使用户可以更专注于自身应用的开发。
AliOS Things 3.0版本新增加了httpc组件(http 客户端组件),httpc组件支持多种RESTful的API调用,包括GET、POST、PUT、HEAD等,也支持https安全协议。

准备工作

参考 AliOS Things Environment SetupAliOS Things 3.0 应用开发指南 搭建好AliOS Things 3.0的应用开发环境。

创建应用工程

参考AliOS Things 3.0 应用开发指南 > AliOS Studio中创建应用工程创建好你的应用工程。

本示例新建的应用工程名称为httpclient_app,选择的开发板为developerkit

编写应用代码

新建好的应用工程文件如下面所示:

.httpclient_app
├── .aos               # AliOS Things 3.0 应用工程描述
├── .vscode            # AliOS Studio 配置文件
├── Config.in          # Menuconfig 配置文件
├── README.md          # 应用说明文档
├── aos.mk             # 编译文件
├── app_main.c         # 应用示例代码
└── k_app_config.h     # 内核配置

添加http组件

aos-cube会自动根据include的头文件来自动添加组件。

http组件需要用到全局宏:BUILD_AOS,所以需要在aos.mk中额外增加一个全局宏定义:

GLOBAL_DEFINES += BUILD_AOS

天气API说明

本示例使用http组件,发送http get请求获取天气数据,天气的API是中国天气网提供的API:http://www.weather.com.cn/data/sk/101210101.html,其中101210101代表是杭州。

使用curl命令可以测试该API接口:

$ curl http://www.weather.com.cn/data/sk/101210101.html
{"weatherinfo":{"city":"杭州","cityid":"101210101","temp":"24.8","WD":"东北风","WS":"小于3级","SD":"81%","AP":"1000.3hPa","njd":"暂无实况","WSE":"<3","time":"17:50","sm":"2.1","isRadar":"1","Radar":"JC_RADAR_AZ9571_JB"}}%

或者也可以在浏览器打开该链接测试API接口。

使用http组件

本示例主要使用到了http如下接口,详细的http对外提供的接口和参数说明请参考include/network/http/http.h

/* httpc 初始化 */
int8_t http_client_initialize(void);

/* 创建一个httpc实例 */
httpc_handle_t httpc_init(httpc_connection_t *settings);

/* 销毁一个httpc实例 */
int8_t httpc_deinit(httpc_handle_t httpc);

/* 发送http请求 */
int8_t httpc_send_request(httpc_handle_t httpc, int8_t method, char *uri,
                          const char *hdr, const char *content_type,
                          const char *param, uint16_t param_len);

/* 构建http请求header */
int32_t httpc_construct_header(char *buf, uint16_t buf_size, const char *name, const char *data);

/* 等待接口http返回 */
int32_t httpc_recv_response(httpc_handle_t httpc, uint8_t *rsp, uint32_t rsp_size,
                            http_rsp_info_t *info, uint32_t timeout);

完整源码

本示例应用的工程源码点击这里下载。

注意:需要更改app_main.c中的WIFI_SSIDWIFI_PASSWD 为你的路由器信息。

aos.mk:
NAME := httpclient_app

$(NAME)_MBINS_TYPE := app
$(NAME)_VERSION := 1.0.0
$(NAME)_SUMMARY := httpclient_app

$(NAME)_SOURCES += app_main.c

GLOBAL_DEFINES += BUILD_AOS

GLOBAL_INCLUDES += ./

$(NAME)_COMPONENTS_CUSTOMIZED := http yloop
$(NAME)_COMPONENTS += $($(NAME)_COMPONENTS_CUSTOMIZED)
app_main.c:
/*
 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
 */

#include <stdio.h>

#include <aos/kernel.h>
#include <aos/yloop.h>
#include <http.h>
#include <network/network.h>

#define WIFI_SSID "aiot"
#define WIFI_PASSWD "12345678"

#define REQ_BUF_SIZE 2048
#define RSP_BUF_SIZE 4096
#define HTTP_UP_HDR_SIZE 128

/* weather api hostname */
#define WEATHER_HOSTNAME "http://www.weather.com.cn/"
/* weather api uri */
#define WEATHER_URI "data/sk/101210101.html"

static httpc_handle_t httpc_handle = 0;
static httpc_connection_t settings;

/* buffer for send & receive */
static uint8_t rsp_buf[RSP_BUF_SIZE] = {0};
static uint8_t req_buf[REQ_BUF_SIZE] = {0};

/* send http get request */
char *get_weather(void)
{
    int fd;
    char hdr[HTTP_UP_HDR_SIZE] = {0};
    int32_t ret;
    http_rsp_info_t rsp_info;

    http_client_initialize();

    /* create socket */
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("alloc socket fd fail\n");
        goto exit;
    }
    memset(&settings, 0, sizeof(settings));
    settings.socket       = fd;
    settings.server_name  = WEATHER_HOSTNAME;
    settings.req_buf      = req_buf;
    settings.req_buf_size = REQ_BUF_SIZE;

    /* httpc initialization */
    if ((httpc_handle = httpc_init(&settings)) == 0) {
        printf("http session init fail\n");
        close(fd);
        goto exit;
    }

    /* construct httc header: set accept content type */
    if ((httpc_construct_header(
            hdr, HTTP_UP_HDR_SIZE, "Accept",
            "text/xml,text/javascript,text/html,application/json")) < 0) {
        printf("http construct header fail\n");
        goto exit;
    }

    /* send get request */
    if ((httpc_send_request(httpc_handle, HTTP_GET, WEATHER_URI, hdr,
                            "application/json", NULL, 0)) != HTTP_SUCCESS) {
        printf("httpc_send_request fail\n");
        goto exit;
    }

    /* get response */
    if ((httpc_recv_response(httpc_handle, rsp_buf, RSP_BUF_SIZE, &rsp_info,
                             10000)) < 0) {
        printf("httpc_recv_response fail\n");
        goto exit;
    }

    printf("http session %x, buf size %d bytes, recv %d bytes data", httpc_handle,
        RSP_BUF_SIZE, rsp_info.rsp_len);
    // if (rsp_info.rsp_len > 0) {
    //     printf("%s", rsp_buf);
    // }

    if (rsp_info.message_complete) {
        // printf("message_complete");
        close(settings.socket);
        httpc_deinit(httpc_handle);
        return rsp_info.body_start;
    }

exit:
    close(settings.socket);
    httpc_deinit(httpc_handle);
    return NULL;
}

/* task for get weather */
static void get_weather_task(void *arg)
{
    char *weather_data = NULL;

    /* get weather data */
    if((weather_data = get_weather()) != NULL){
        aos_msleep(200);
        printf("********************** weather data **********************\r\n");
        printf("%s\r\n", weather_data);
        printf("**********************************************************\r\n");
        return;
    }

    printf("weather request error\r\n");
}

/* wifi event */
static void wifi_service_event(input_event_t *event, void *priv_data)
{
    static char ip[16] = {0};
    static int get_weather_started = 0;

    if (event->type != EV_WIFI && event->code != CODE_WIFI_ON_GOT_IP) {
        return;
    }

    netmgr_wifi_get_ip(ip);

    /* start up only once */
    if (get_weather_started == 1) {
        return;
    }

    /* check if ip is available */
    if (0 == strcmp(ip, "0.0.0.0")) {
        printf("ip invailable\n");
        return;
    }
    get_weather_started = 1;
    printf("wifi connected, ip:%s\n", ip);

    aos_task_new("get_weather", get_weather_task, NULL, 1024 * 4);
}

/* task for connect wifi */
static void wifi_connect(void *arg)
{
    /* network init */
    netmgr_init();
    netmgr_start(false);
    aos_msleep(100);

    /* connect to wifi */
    printf("\r\nConnecting to wifi: ssid:[%s], passwd:[%s]\r\n", WIFI_SSID, WIFI_PASSWD);
    netmgr_connect(WIFI_SSID, WIFI_PASSWD, 10 * 1000);
}
/**********************user code*************************/
int application_start(int argc, char *argv[])
{
#ifdef WITH_SAL
    sal_add_dev(NULL, NULL);
    sal_init();
#endif

    /* register wifi event */
    aos_register_event_filter(EV_WIFI, wifi_service_event, NULL);

    aos_task_new("wifi_connect", wifi_connect, NULL, 2048);

    /* loop for schedule */
    aos_loop_run();
}

编译运行

点击编译和烧录。运行后,在串口日志最后面就能看的获取到的天气信息。

运行效果:
[   0.050]<A>AOS sensor:  drv_acc_st_lsm6dsl_init successfully

[   0.060]<A>AOS sensor:  drv_gyro_st_lsm6dsl_init gyro do not need reset

[   0.070]<A>AOS sensor:  drv_gyro_st_lsm6dsl_init successfully

[   0.080]<A>AOS sensor:  drv_als_liteon_ltr553_init successfully

[   0.090]<A>AOS sensor:  drv_ps_liteon_ltr553_init successfully

[   0.100]<A>AOS sensor:  drv_baro_bosch_bmp280_init successfully

[   0.110]<A>AOS sensor:  drv_mag_memsic_mmc3680kj_init successfully

[   0.120]<A>AOS sensor:  drv_humi_sensirion_shtc1_init successfully

[   0.130]<A>AOS sensor:  drv_temp_sensirion_shtc1_init successfully

             Welcome to AliOS Things
[   0.150]<E>sal_wifi Uart dev is not configured, use the default cfg

uart 1 enter uart_receive_start_dma instance 0x40004800ip invailable

Connecting to wifi: ssid:[aiot], passwd:[12345678]
wifi connected, ip:192.168.43.111
[[hhttttppcc]][[000088665500]]  hhttttppcc__sseenndd__rreeqquueesstt,,  sseenndd  rreeqquueesstt  hheeaaddeerr

vGoErTk s/pdaactea//gsikt/h1u0b1/2A1l0i1O0S1-.Thhtimnlg sH/TbToPa/r1d./1d
2Ulsoepre-rAkgietn/ta:o sA/lbioOaSr-dH_TcTlPi-.Ccl i2e1n6t
1

Cache-Control: no-cache
Connection: close
Host: www.weather.com.cn
Accept: text/xml,text/javascript,text/html,application/json
Content-Type: application/json


socket 0, len 238
[httpc][009130] httpc_send_request, connect 0
[httpc][009160] httpc_send_request, send 238, ret 0
[httpc][019170] on_message_begin, HTTP response (headers), method GET
[httpc][019170] on_status, HTTP response status OK
[httpc][019180] print_header_field, len 4, Date
[httpc][019190] print_header_field, len 29, Wed, 09 Oct 2019 07:32:13 GMT
[httpc][019200] print_header_field, len 12, Content-Type
[httpc][019200] print_header_field, len 9, text/html
[httpc][019210] print_header_field, len 17, Transfer-Encoding
[httpc][019220] print_header_field, len 7, chunked
[httpc][019220] print_header_field, len 10, Connection
[httpc][019230] print_header_field, len 5, close
[httpc][019240] print_header_field, len 6, Server
[httpc][019240] print_header_field, len 9, openresty
[httpc][019250] print_header_field, len 16, X-Xss-Protection
[httpc][019260] print_header_field, len 1, 1
[httpc][019260] print_header_field, len 10, Set-Cookie
[httpc][019270] print_header_field, len 8, HttpOnly
[httpc][019280] print_header_field, len 3, Age
[httpc][019280] print_header_field, len 4, 2068
[httpc][019290] print_header_field, len 5, X-Via
[httpc][019300] print_header_field, len 125, 1.1 PSbjsdBGPvu28:10 (Cdn Cache Server V2.0), 1.1 zhdx147:10 (Cdn Cache Server V2.0), 1.1 huadxin69:7 (Cdn Cache Server V2.0)
[httpc][019320] on_headers_complete, headers complete
[httpc][019320] on_message_complete, HTTP GET response (complete)
http session 20002298, buf size 4096 bytes, recv 578 bytes data[  19.340]<E>sal_wifi HAL_SAL_Close 778 failed
********************** weather data **********************
{"weatherinfo":{"city":"杭州","cityid":"101210101","temp":"24.8","WD":"东北风","WS":"小于3级","SD":"81%","AP":"1000.3hPa","njd":"暂无实况","WSE":"<3","time":"17:50","sm":"2.1","isRadar":"1","Radar":"JC_RADAR_AZ9571_JB"}}

**********************************************************

参考文档

相关文章
|
5月前
|
XML JSON 网络协议
SAP ABAP Gateway Client 的 ABAP 实现,重用 HTTP Connection
SAP ABAP Gateway Client 的 ABAP 实现,重用 HTTP Connection
|
9月前
HTTP client
HTTP client
67 0
|
网络协议 安全 Java
HTTP Client 学习笔记 (一) 初遇篇
HTTP Client 学习笔记 (一) 初遇篇
HTTP Client 学习笔记 (一) 初遇篇
|
JSON 网络协议 Java
你会换掉Postman吗?我正在用HTTP Client...
相信大家都用过POSTMAN吧,后端在开发的时候写完接口总得去自测调用一下,看符不符合自己的预期。
115 0
你会换掉Postman吗?我正在用HTTP Client...
|
JSON 数据格式
使用Angular的http client发送请求,请求response总是被当成json类型处理
奇怪的问题,我的req.responseType字段没有显式赋值,而默认值为json:
使用Angular的http client发送请求,请求response总是被当成json类型处理
|
Web App开发 开发者
Angular http client发起的请求在Chrome开发者工具network标签页里观察到的界面
Angular http client发起的请求在Chrome开发者工具network标签页里观察到的界面
Angular http client发起的请求在Chrome开发者工具network标签页里观察到的界面
使用Angular HTTP client对数据模型进行删除操作
使用Angular HTTP client对数据模型进行删除操作
使用Angular HTTP client对数据模型进行删除操作
使用Angular HTTP client对数据模型进行创建操作
使用Angular HTTP client对数据模型进行创建操作
使用Angular HTTP client对数据模型进行创建操作
使用Angular HTTP client对数据模型进行update操作
使用Angular HTTP client对数据模型进行update操作
使用Angular HTTP client对数据模型进行update操作
|
JavaScript 应用服务中间件 Linux
开源项目推荐:C/C++语言版本的http server和client,请关注RESTful
开源项目推荐:C/C++语言版本的http server和client,请关注RESTful
3002 0
相关产品
物联网平台
物联网边缘计算
物联网络管理平台
推荐文章
更多