简介
AliOS Things 3.0 版本于 9 月 27 日在云栖大会正式发布, 在新版本中带来了全新的应用开发框架, 帮助用户快速构建自己的应用. 使用户可以更专注于自身应用的开发.
AliOS Things 3.0 版本新增加了 httpc 组件 (http 客户端组件),httpc 组件支持多种 RESTful 的 API 调用, 包括 GET,POST,PUT,HEAD 等, 也支持 https 安全协议.
本示例是基于 AliOS Things 3.0 应用开发框架做的一个简单的 http client 应用, 通过 http API 请求获取当前的天气信息.
准备工作
参考 AliOS Things Environment Setup 和 AliOS 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_SSID 和 WIFI_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");
- }
- /* Wi-Fi 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 Wi-Fi */
- static void wifi_connect(void *arg)
- {
- /* network init */
- netmgr_init();
- netmgr_start(false);
- aos_msleep(100);
- /* connect to Wi-Fi */
- 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 Wi-Fi 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 Wi-Fi: ssid:[aiot], passwd:[12345678]
- Wi-Fi 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"}}
- **********************************************************
参考文档
AliOS Things 3.0 应用开发指南
使用 AliOS Things3.0 快速构建用户应用 BlinkAPP
来源: https://yq.aliyun.com/articles/720323