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

简介: AliOS Things 3.0版本于9月27日在云栖大会正式发布,在新版本中带来了全新的应用开发框架,帮助用户快速构建自己的应用。使用户可以更专注于自身应用的开发。 本示例是基于AliOS Things 3.0应用开发框架做的一个简单的http client应用,通过http API请求获取当前的天气信息。

简介

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 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"}}

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

参考文档

目录
相关文章
|
1月前
|
JSON Java Apache
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
153 3
|
1月前
|
前端开发 JavaScript 安全
前端性能调优:HTTP/2与HTTPS在Web加速中的应用
【10月更文挑战第27天】本文介绍了HTTP/2和HTTPS在前端性能调优中的应用。通过多路复用、服务器推送和头部压缩等特性,HTTP/2显著提升了Web性能。同时,HTTPS确保了数据传输的安全性。文章提供了示例代码,展示了如何使用Node.js创建一个HTTP/2服务器。
66 3
|
1月前
|
前端开发 UED 开发者
CSS Sprites和图标字体在网页图标加载优化中的应用。CSS Sprites通过合并多图标减少HTTP请求,提升加载速度
本文探讨了CSS Sprites和图标字体在网页图标加载优化中的应用。CSS Sprites通过合并多图标减少HTTP请求,提升加载速度;图标字体则以字体形式呈现图标,便于调整样式。文章分析了两者的优缺点及应用场景,并提供了应用技巧和注意事项,旨在帮助开发者提升页面性能,改善用户体验。
26 5
|
1月前
|
缓存 安全 网络安全
HTTP/2与HTTPS在Web加速中的应用
HTTP/2与HTTPS在Web加速中的应用
|
1月前
|
缓存 安全 前端开发
HTTP 协议的请求方法在实际应用中有哪些注意事项?
【10月更文挑战第29天】HTTP协议的请求方法在实际应用中需要根据具体的业务场景和需求,合理选择和使用,并注意各种方法的特点和限制,以确保网络通信的安全、高效和数据的一致性。
|
1月前
|
前端开发 安全 应用服务中间件
前端性能调优:HTTP/2与HTTPS在Web加速中的应用
【10月更文挑战第26天】随着互联网的快速发展,前端性能调优成为开发者的重要任务。本文探讨了HTTP/2与HTTPS在前端性能优化中的应用,介绍了二进制分帧、多路复用和服务器推送等特性,并通过Nginx配置示例展示了如何启用HTTP/2和HTTPS,以提升Web应用的性能和安全性。
40 3
|
1月前
|
网络协议 前端开发 API
HTTP 和 TCP 协议的应用场景有哪些不同
【10月更文挑战第25天】HTTP(超文本传输协议)和 TCP(传输控制协议)处于网络协议栈的不同层次,各自具有独特的功能和特点,因此它们的应用场景也存在明显的差异。
|
传感器 消息中间件 物联网
HCIA物联网初级考试-第五章物联网操作系统及感知层开发介绍
HCIA物联网初级考试-第五章物联网操作系统及感知层开发介绍
HCIA物联网初级考试-第五章物联网操作系统及感知层开发介绍
|
算法 AliOS-Things 物联网
HaaS100开发调试系列 之 定位AliOS Things内存及Crash问题
本文主要说开发调试过程中经常遇到的内存问题。
347 15
HaaS100开发调试系列 之 定位AliOS Things内存及Crash问题
|
AliOS-Things 物联网 编译器
使用HaaS Studio开发AliOS Things C/C++应用
本文章将介绍使用HaaS Studio 进行AliOS-Things C/C++应用开发。
使用HaaS Studio开发AliOS Things C/C++应用