本文以C Link SDK中的Demo文件./demos/http_basic_demo
为例,介绍如何调用Link SDK的API,将HTTPS协议的设备接入物联网平台并进行消息收发。
步骤一:初始化
配置底层依赖和日志输出。aiot_http_init,创建客户端实例,并初始化默认参数。
/* 配置SDK的底层依赖 */
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
/* 配置SDK的日志输出 */
aiot_state_set_logcb(demo_state_logcb);
...
...
/* 创建1个HTTPS客户端实例并内部初始化默认参数 */
http_handle = aiot_http_init();
步骤二:配置功能
调用aiot_http_setopt,配置以下功能。
- 配置连接参数。
- 配置事件回调。
更多功能的配置项,请参见aiot_http_option_t。
- 配置连接参数。
- 示例代码:
char *http_host = "iot-as-http.cn-shanghai.aliyuncs.com";
…
aiot_sysdep_network_cred_t cred;
char *product_key = "a18wP******";
char *device_name = "LightSwitch";
char *device_secret = "uwMTmVAMnGGHaAkqmeDY6cHxxB******";
…
…
/* 配置HTTPS服务器域名。 */
aiot_http_setopt(http_handle, AIOT_HTTPOPT_HOST, (void *)host);
/* 配置服务器端口。 */
aiot_http_setopt(http_handle, AIOT_HTTPOPT_PORT, (void *)&port);
/* 配置设备安全凭证。 */
aiot_http_setopt(http_handle, AIOT_HTTPOPT_NETWORK_CRED, &cred);
/* 配置设备ProductKey。 */
aiot_http_setopt(http_handle, AIOT_HTTPOPT_PRODUCT_KEY, product_key);
/* 配置设备DeviceName。 */
aiot_http_setopt(http_handle, AIOT_HTTPOPT_DEVICE_NAME, device_name);
/* 配置设备DeviceSecret。 */
aiot_http_setopt(http_handle, AIOT_HTTPOPT_DEVICE_SECRET, device_secret);
- 相关参数:
参数 |
示例 |
说明 |
http_host |
iot-06z00ax1o******.http.iothub.aliyuncs.com |
设备的接入域名。
- 企业版实例和新版公共实例:在实例详情页面的开发配置面板,查看接入域名。
- 旧版公共实例:接入域名格式为
https://iot-as-http.${YourRegionId}.aliyuncs.com 。
新旧版公共实例和企业版实例、以及接入域名的更多信息,请参见查看实例终端节点。
|
product_key |
a18wP****** |
设备认证信息。更多信息,请参见获取设备认证信息。
本例程的身份认证方式为一机一密。
|
device_name |
LightSwitch |
device_secret |
uwMTmVAMnGGHaAkqmeDY6cHxxB****** |
- 配置状态监控。
- 配置状态监控的回调函数。
- 示例代码:
int main(int argc, char *argv[])
{
...
...
/* 配置数据到达时, SDK应调用的用户回调函数 */
aiot_http_setopt(http_handle, AIOT_HTTPOPT_RECV_HANDLER, demo_http_recv_handler);
/* 配置内部状态变化时, SDK应调用的用户回调函数 */
aiot_http_setopt(http_handle, AIOT_HTTPOPT_EVENT_HANDLER, demo_http_event_handler);
}
- 相关参数:
配置项 |
示例值 |
说明 |
AIOT_HTTPOPT_RECV_HANDLER |
demo_http_recv_handler |
当设备接收到应答报文后,触发该函数,执行对应处理。 |
AIOT_HTTPOPT_EVENT_HANDLER |
demo_http_event_handler |
当Token变化时,触发该回调函数,以确保Token的有效性。 |
- 定义状态监控回调函数。
- 在Token变化时,触发回调函数,设置执行操作。
void demo_http_event_handler(void *handle, const aiot_http_event_t *event, void *user_data)
{
int32_t res;
/* Token失效事件处理 */
if (event->type == AIOT_HTTPEVT_TOKEN_INVALID) {
printf("token invalid, invoke iot_http_auth to get new token\n");
res = aiot_http_auth(handle);
printf("aiot_http_auth in callback, res = -0x%04x\r\n", -res);
}
}
- 在读取到网络报文时,触发回调函数,执行设置的处理。示例仅做打印处理,您在编写处理逻辑时,需考虑以下几点。
- 应答报文的参数说明,请参见HTTPS连接通信。
- 正常接收报文含AIOT_HTTPRECV_STATUS_CODE、AIOT_HTTPRECV_HEADER和 AIOT_HTTPRECV_BODY三个事件,分别表示:通信是否成功、报文的类型和报文的包体。
- 根据业务需要,处理状态码。状态码的更多信息,请参见HTTP状态码。
void demo_http_recv_handler(void *handle, const aiot_http_recv_t *packet, void *userdata)
{
switch (packet->type) {
case AIOT_HTTPRECV_STATUS_CODE: {
/* TODO: 以下代码如果不被注释, SDK收到HTTPS报文时, 会通过这个用户回调打印HTTPS状态码, 如404, 200, 302等。 */
/* printf("status code: %d\n", packet->data.status_code.code); */
}
break;
case AIOT_HTTPRECV_HEADER: {
/* TODO: 以下代码如果不被注释, SDK收到HTTPS报文时, 会通过该回调打印HTTPS首部, 如Content-Length等。 */
/* printf("key: %s, value: %s\n", packet->data.header.key, packet->data.header.value); */
}
break;
/* TODO: 如果需要处理物联网平台的HTTPS回应报文, 在此处修改。当前示例仅打印回应。 */
case AIOT_HTTPRECV_BODY: {
printf("%.*s\r\n", packet->data.body.len, packet->data.body.buffer);
}
break;
default: {
}
break;
}
}
步骤三:请求连接
调用aiot_http_auth,根据配置连接的参数,向指定的物联网平台HTTPS服务器,发送身份认证请求,获取Token。
/* 设备认证, 获取Token */
res = aiot_http_auth(http_handle);
if (res == 0) {
printf("aiot_http_auth succeed\r\n");
} else {
/* 如果认证失败, 就销毁实例, 回收资源, 退出程序 */
printf("aiot_http_auth failed, res = -0x%04x\r\n", -res);
aiot_http_deinit(&http_handle);
return -1;
}
步骤四:发送消息
调用aiot_http_send,在demo_http_post_lightswitch
中,向指定Topic发送消息。
说明
- 例程仅打印发送的消息。实际业务中,您需自定义函数
demo_http_post_lightswitch
。
- 您需删除例程中代码两边的注释符号,以演示设备向物联网平台上报消息。
- 示例代码:
int32_t demo_http_post_lightswitch(void *handle)
{
char data[] = "{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}";
int32_t res;
res = aiot_http_send(handle,
"/a1wAf******/LightSwitch/user/update",
(uint8_t *)data,
strlen(data));
if (res < 0) {
printf("aiot_http_send res = -0x%04X\r\n", -res);
return res;
}
…
…
}
- 相关参数:
参数 |
示例 |
说明 |
data[] |
{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}} |
上报至物联网平台的消息内容。 由于示例消息的Topic类型为自定义,因此数据格式可自定义。
关于数据格式的更多信息,请参见数据格式。
|
topic |
/a1wAf******/LightSwitch/user/update |
拥有发布权限的Topic。
a18wP****** 为设备的ProductKey。
LightSwitch 为设备的DeviceName。
设备通过该Topic向物联网平台发送消息。关于Topic的更多信息,请参见什么是Topic。
|
步骤五:接收应答
消息发送后,物联网平台返回应答报文。设备端调用aiot_http_recv接收HTTPS应答数据,根据事件回调函数,执行对应处理。
res = aiot_http_recv(handle);
if (res >= 0) {
/* 成功接收到服务器应答, 且业务应答码为0, 说明数据上报成功 */
return 0;
} else {
printf("aiot_http_recv res = -0x%04X\r\n", -res);
return -1;
}
}
步骤六:退出程序
调用aiot_http_deinit,销毁HTTPS客户端实例,释放资源。
aiot_http_deinit(&http_handle);
printf("program exit as normal return\r\n");
printf("\r\n");
return 0;