MQTT 5.0概述
MQTT是一种轻量级的物联网协议,大幅度降低了网络带宽和设备资源的需求,并支持可靠的数据传输,因此MQTT已成为IoT领域最广泛应用的协议之一。随着IoT设备规模和应用场景的不断扩大,MQTT 5.0协议应运而生,以满足更多新场景需求。本文为您介绍MQTT 5.0的新特性。
背景信息
目前,阿里云物联网平台已支持MQTT 3.1、3.1.1、5.0版本协议,具体的协议请参见MQTT 5.0、MQTT 3.1.1和 MQTT 3.1。
阿里云物联网平台已经具备标准MQTT Broker功能,并在此基础上增加了服务端订阅、云产品流转和云端SDK功能,以加快云端业务应用的开发。更多信息,请参见什么是服务端订阅、云产品流转概述和MQTT 5.0接入概述。
使用限制
设备身份注册成功后,针对同一设备身份信息,只可选择一种通信协议接入物联网平台,不可多种类型通信协议同时混用。即一个设备选择使用MQTT 5.0通信协议后,不可再使用MQTT 3.1、3.1.1通信协议。
MQTT 5.0新特性
MQTT 5.0在MQTT 3.1.1的基础上进行功能扩展,在不增加资源消耗、不降低易用性的情况下,提高物联网设备的性能、扩展能力和互操作性。
特性 | 说明 |
用户属性 | 消息头类似于HTTP的Header,可以由用户自定义Key-Value属性,并且支持可扩展的消息属性。 |
主题别名 | 使用4字节整型数替换较长的Topic字符串,降低资源消耗。 |
会话过期 | 支持在设备离线时,设置保留设备端与服务端之间会话信息的时间。 |
消息过期 | 发布消息时支持设置消息过期时间,避免订阅端收到过期消息。 |
遗嘱消息 | 设备异常断开连接时,订阅者仍能接收到设备之前发布的消息。 |
保留消息 | 设备发布的消息可以设置为保留,这样新的订阅者在订阅时就能接收到之前保留的消息。 |
共享订阅 | 多个订阅者可消费同一个topic消息,帮助用户搭建负载均衡系统。 |
订阅选项 | 订阅增加选项设置,可以剔除不需要的消息,提高传输效率。 |
请求与响应模式 | 扩展请求/响应模式,类似于HTTP协议的RPC调用。 |
消息格式描述 | 消息增加Payload格式说明,帮助用户实现消息的透明流转,支持可变的消息负载。 |
增强端云交互 | 支持功能参数协商、增强错误码、服务端主动断开等特性,提高问题排查效率。 |
概述
MQTT是基于TCP/IP协议栈构建的异步通信消息协议,是一种轻量级的发布、订阅信息传输协议。物联网平台已支持MQTT 5.0协议,提高了系统性能、稳定性和可伸缩性。您可以通过配置C Link SDK,将设备接入阿里云物联网平台。
前提条件
- 已准备开发环境。
- 已获取C Link SDK。定制SDK时,在SDK定制页面的连接物联网平台协议区域,选中MQTT 5.0.0。
- 已获取设备认证信息。
- 已了解支持的MQTT 5.0特性。
功能原理
应用程序通过调用C Link SDK的API,基于MQTT 5.0的协议,与物联网平台建立连接。
如下功能时序图,以设备的应用程序(./demos/mqtt_v5_basic_demo.c
)为例,介绍应用程序实现该功能的流程。
- MQTT 5.0接入功能API的更多信息,请参见aiot_mqtt_api.h。
- MQTT 5.0属性管理功能API的更多信息,请参见aiot_mqtt_props_api.h。
使用示例
使用示例
本文以C Link SDK中的Demo文件./demos/mqtt_v5_basic_demo.c
为例,介绍如何调用C Link SDK的API,将MQTT 5.0协议的设备接入物联网平台并进行消息收发。
背景信息
MQTT 5.0接入的更多信息,请参见概述。
步骤一:初始化
- 添加头文件。
#include "aiot_state_api.h" #include "aiot_sysdep_api.h" #include "aiot_mqtt_api.h"
- 配置底层依赖和日志输出。
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile); aiot_state_set_logcb(demo_state_logcb);
- 调用aiot_mqtt_init,创建MQTT客户端实例,并初始化默认参数。
mqtt_handle = aiot_mqtt_init(); if (mqtt_handle == NULL) { printf("aiot_mqtt_init failed\n"); return -1; }
步骤二:配置功能
调用aiot_mqtt_setopt,配置以下功能。更多功能的配置项,请参见aiot_mqtt_option_t。
- 配置连接参数。
- 示例代码:
char *product_key = "a18wP******"; char *device_name = "LightSwitch"; char *device_secret = "uwMTmVAMnGGHaAkqmeDY6cHxxB******"; char *mqtt_host = "iot-06z00ax1o******.mqtt.iothub.aliyuncs.com"; ... ... /* 配置MQTT协议的版本 */ protocol_version = AIOT_MQTT_VERSION_5_0; aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_VERSION, (void *)&protocol_version); /* 配置MQTT服务器地址。 */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_HOST, (void *)url); /* 配置MQTT服务器端口。 */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PORT, (void *)&port); /* 配置设备ProductKey。 */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PRODUCT_KEY, (void *)product_key); /* 配置设备DeviceName。 */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_NAME, (void *)device_name); /* 配置设备DeviceSecret。 */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_SECRET, (void *)device_secret); /* 配置网络连接的安全凭据。 */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_NETWORK_CRED, (void *)&cred); /* 如果要使用MQTT 5.0的assigned clientId功能, 需要将use_assigned_clientid置为1 */ uint8_t use_assigned_clientid = 0; aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_ASSIGNED_CLIENTID, (void *)(&use_assigned_clientid));
- 相关参数:参数示例说明mqtt_hostiot-06z00ax1o******.mqtt.iothub.aliyuncs.com设备接入域名。
- 企业版实例和新版公共实例:在实例详情页面的开发配置面板,查看接入域名。
- 旧版公共实例:接入域名格式为
${YourProductKey}.iot-as-mqtt.${YourRegionId}.aliyuncs.com
。
assigned clientId
功能时,需要将use_assigned_clientid
置为1。 - MQTT保活说明:重要C Link SDK具备保活能力,您可以设置以下配置项,自定义设备连接的保活心跳。如果不配置,则取默认值。配置项默认值说明AIOT_MQTTOPT_HEARTBEAT_MAX_LOST2可容忍的心跳丢失阈值。即:心跳请求报文达到设置的次数后,发起重连。AIOT_MQTTOPT_HEARTBEAT_INTERVAL_MS25,000每次发起重连之间的间隔时间。单位毫秒, 取值范围:1,000~1,200,000。AIOT_MQTTOPT_KEEPALIVE_SEC1,200可容忍的心跳丢失时间阈值。即:失去心跳后,设置的时间内,允许发起重连。单位秒,取值范围:30~1,200。建议取值大于300。
- 示例代码:
- 配置状态监控和消息回调。
- 配置状态监控回调函数。
- 示例代码:
int main(int argc, char *argv[]) { ... ... /* 配置MQTT默认消息接收回调函数。 */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_RECV_HANDLER, (void *)demo_mqtt_default_recv_handler); /* 配置MQTT事件回调函数。 */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_EVENT_HANDLER, (void *)demo_mqtt_event_handler); ... ... }
- 相关参数:配置项示例值说明AIOT_MQTTOPT_RECV_HANDLERdemo_mqtt_default_recv_handler当接收消息时,根据该回调函数定义的处理逻辑,执行对应的处理。AIOT_MQTTOPT_EVENT_HANDLERdemo_mqtt_event_handler当设备连接状态发生变化时,根据该回调函数定义的处理逻辑,执行对应的处理。
- 示例代码:
- 定义状态监控的回调函数。重要
- 请勿将事件的处理逻辑,定义得过于耗时,以免阻塞收包线程。
- 连接状态的变化包括网络异常、自动重连已成功、已断开连接等。
- 如果要根据连接状态的变化做应对处理,可在
TODO
处,按照需要修改代码。
/* MQTT事件回调函数, 当网络连接、重连或断开时,触发该函数, 事件定义见core/aiot_mqtt_api.h。 */ void demo_mqtt_event_handler(void *handle, const aiot_mqtt_event_t *event, void *userdata) { switch (event->type) { /* 调用了aiot_mqtt_connect()接口, 与MQTT服务器建立连接。 */ case AIOT_MQTTEVT_CONNECT: { printf("AIOT_MQTTEVT_CONNECT\n"); /* TODO: 处理SDK建立连接成功, 不可在此调用耗时较长的阻塞函数。 */ } break; /* SDK因网络状况被动断开连接后, 成功自动发起重连。 */ case AIOT_MQTTEVT_RECONNECT: { printf("AIOT_MQTTEVT_RECONNECT\n"); /* TODO: 处理SDK重连成功, 不可在此调用耗时较长的阻塞函数。 */ } break; /* SDK因网络状况被动断开了连接, network底层读写失败, heartbeat没有按预期得到服务端心跳应答。 */ case AIOT_MQTTEVT_DISCONNECT: { char *cause = (event->data.disconnect == AIOT_MQTTDISCONNEVT_NETWORK_DISCONNECT) ? ("network disconnect") : ("heartbeat disconnect"); printf("AIOT_MQTTEVT_DISCONNECT: %s\n", cause); /* TODO: 处理SDK被动断开连接, 不可在此调用耗时较长的阻塞函数。 */ } break; default: { } } }
- 定义消息接收的回调函数。重要
- 请勿将消息的处理逻辑,定义得过于耗时,以免阻塞收包线程。
- 如果您要根据接收的消息做应对处理,可在
TODO
处,按照需要修改代码。
/* MQTT默认消息处理回调, 当SDK从服务器收到MQTT消息时, 且无对应用户回调处理时被调用 */ void demo_mqtt_default_recv_handler(void *handle, const aiot_mqtt_recv_t *packet, void *userdata) { switch (packet->type) { case AIOT_MQTTRECV_HEARTBEAT_RESPONSE: { printf("heartbeat response\n"); /* TODO: 处理服务器对心跳的回应, 一般不处理 */ } break; case AIOT_MQTTRECV_SUB_ACK: { printf("suback, res: -0x%04X, packet id: %d, max qos: %d\n", -packet->data.sub_ack.res, packet->data.sub_ack.packet_id, packet->data.sub_ack.max_qos); /* TODO: 处理服务器对订阅请求的回应, 一般不处理 */ } break; case AIOT_MQTTRECV_UNSUB_ACK: { printf("unsuback, , packet id: %d\n", packet->data.unsub_ack.packet_id); /* TODO: 处理服务器对订阅请求的回应, 一般不处理 */ } break; case AIOT_MQTTRECV_PUB: { printf("pub, qos: %d, topic: %.*s\n", packet->data.pub.qos, packet->data.pub.topic_len, packet->data.pub.topic); printf("pub, payload: %.*s\n", packet->data.pub.payload_len, packet->data.pub.payload); printf("pub, payload len: %x\n", packet->data.pub.payload_len); aiot_mqtt_props_print(packet->data.pub.props); } break; case AIOT_MQTTRECV_PUB_ACK: { printf("puback, packet id: %d\n", packet->data.pub_ack.packet_id); /* TODO: 处理服务器对QoS1上报消息的回应, 一般不处理 */ } break; case AIOT_MQTTRECV_CON_ACK: { aiot_mqtt_props_print(packet->data.con_ack.props); } break; case AIOT_MQTTRECV_DISCONNECT: { printf("server disconnect, reason code: 0x%x\n", packet->data.server_disconnect.reason_code); } break; default: { } } }
- 配置状态监控回调函数。
步骤三:请求连接
调用aiot_mqtt_connect_v5,根据配置连接的参数,向物联网平台,发起连接认证请求。
说明
示例代码中添加的用户属性(MQTT_PROP_ID_USER_PROPERTY
)更多信息,请参见mqtt_property_identify_t。
mqtt_properties_t *conn_props = aiot_mqtt_props_init();
mqtt_property_t user_prop = {
.id = MQTT_PROP_ID_USER_PROPERTY,
.value.str_pair.key.len = strlen("demo_key"),
.value.str_pair.key.value = (uint8_t *)"demo_key",
.value.str_pair.value.len = strlen("demo_value"),
.value.str_pair.value.value = (uint8_t *)"demo_value",
};
aiot_mqtt_props_add(conn_props, &user_prop);
/* 通过MQTT 5.0的方式与服务器建连 */
res = aiot_mqtt_connect_v5(mqtt_handle, NULL, conn_props);
aiot_mqtt_props_deinit(&conn_props);
if (res < STATE_SUCCESS) {
/* 尝试建立连接失败, 销毁MQTT实例, 回收资源 */
aiot_mqtt_deinit(&mqtt_handle);
printf("aiot_mqtt_connect failed: -0x%04X\n\r\n", -res);
printf("please check variables like mqtt_host, produt_key, device_name, device_secret in demo\r\n");
return -1;
}
步骤四:开启保活线程
调用aiot_mqtt_process,向服务器发送心跳报文,使设备保持长连接状态,并重发QoS=1
的未应答报文。
- 开启保活线程。
res = pthread_create(&g_mqtt_process_thread, NULL, demo_mqtt_process_thread, mqtt_handle); if (res < 0) { printf("pthread_create demo_mqtt_process_thread failed: %d\n", res); return -1; }
- 设置保活线程处理函数。
void *demo_mqtt_process_thread(void *args) { int32_t res = STATE_SUCCESS; while (g_mqtt_process_thread_running) { res = aiot_mqtt_process(args); if (res == STATE_USER_INPUT_EXEC_DISABLED) { break; } sleep(1); } return NULL; }
步骤五:开启接收线程
调用aiot_mqtt_recv,收取服务器下发的MQTT消息,根据消息回调函数,执行对应处理。在断线时自动重连,根据事件回调函数,执行对应处理。
- 开启接收线程。
res = pthread_create(&g_mqtt_recv_thread, NULL, demo_mqtt_recv_thread, mqtt_handle); if (res < 0) { printf("pthread_create demo_mqtt_recv_thread failed: %d\n", res); return -1; }
- 设置接收线程处理函数。
void *demo_mqtt_recv_thread(void *args) { int32_t res = STATE_SUCCESS; while (g_mqtt_recv_thread_running) { res = aiot_mqtt_recv(args); if (res < STATE_SUCCESS) { if (res == STATE_USER_INPUT_EXEC_DISABLED) { break; } sleep(1); } } return NULL; }
步骤六:订阅Topic
调用aiot_mqtt_sub_v5,订阅指定Topic。
- 示例代码:
/* MQTT 订阅topic功能示例, 请根据自己的业务需求进行使用 */ { char *sub_topic = "/sys/${YourProductKey}/${YourDeviceName}/thing/event/property/post_reply"; mqtt_properties_t *sub_props = aiot_mqtt_props_init(); aiot_mqtt_props_add(sub_props, &user_prop); /* 订阅选项 */ sub_options_t opts = { .no_local = 1, .qos = 1, .retain_as_publish = 1, .retain_handling = 1, }; res = aiot_mqtt_sub_v5(mqtt_handle, sub_topic, &opts, NULL, NULL, sub_props); aiot_mqtt_props_deinit(&sub_props); if (res < 0) { printf("aiot_mqtt_sub failed, res: -0x%04X\n", -res); aiot_mqtt_deinit(&mqtt_handle); return -1; } }
说明- 示例代码中添加的用户属性(
MQTT_PROP_ID_USER_PROPERTY
)更多信息,请参见mqtt_property_identify_t。 - 添加订阅选项的详细内容,请参见sub_options_t。
- 示例代码中添加的用户属性(
- 相关参数:参数示例说明sub_topic/a18wP******/LightSwitch/user/get拥有订阅权限的Topic。其中:
a18wP******
为设备的ProductKey。LightSwitch
为设备的DeviceName。
步骤七:发送消息
调用aiot_mqtt_pub_v5,向指定Topic发送消息。
- 示例代码:
mqtt_properties_t *pub_props = aiot_mqtt_props_init(); /* MQTT 发布消息功能示例, 请根据自己的业务需求进行使用 */ char *pub_topic = "/sys/${YourProductKey}/${YourDeviceName}/thing/event/property/post"; char *pub_payload = "{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}"; mqtt_property_t response_prop = { .id = MQTT_PROP_ID_RESPONSE_TOPIC, .value.str.len = strlen(pub_topic), .value.str.value = (uint8_t *)pub_topic, }; char *demo_data_str = "12345"; mqtt_property_t correlation_prop = { .id = MQTT_PROP_ID_CORRELATION_DATA, .value.str.len = strlen(demo_data_str), .value.str.value = (uint8_t *)demo_data_str, }; aiot_mqtt_props_add(pub_props, &response_prop); aiot_mqtt_props_add(pub_props, &correlation_prop); res = aiot_mqtt_pub_v5(mqtt_handle, pub_topic, (uint8_t *)pub_payload, (uint32_t)(strlen(pub_payload)), 1,0, pub_props); if (res < 0) { printf("aiot_mqtt pub failed, res: -0x%04X\n", -res); aiot_mqtt_deinit(&mqtt_handle); return -1; }
说明示例代码中添加的用户属性(MQTT_PROP_ID_USER_PROPERTY
)更多信息,请参见mqtt_property_identify_t。 - 相关参数:参数示例说明pub_topic/a18wP******/LightSwitch/user/update拥有发布权限的Topic。其中:
a18wP******
为设备的ProductKey。LightSwitch
为设备的DeviceName。
设备与物联网平台建立MQTT通信后,请确保通信量不超过阈值。
步骤八:断开连接
调用aiot_mqtt_disconnect_v5,向物联网平台发送断开连接的报文,然后断开网络连接。
示例代码中添加的用户属性(MQTT_PROP_ID_USER_PROPERTY
)更多信息,请参见mqtt_property_identify_t。
说明
MQTT接入常应用于长连接的设备,程序通常不会运行至此。例程的主线程任务为配置参数并成功建立连接。连接建立后,主线程可进入休眠。
{
mqtt_properties_t *disconn_props = aiot_mqtt_props_init();
/* reason code 0x0 表示Normal disconnection */
int demo_reason_code = 0x0;
char *demo_reason_string = "normal_exit";
mqtt_property_t reason_prop = {.id = MQTT_PROP_ID_REASON_STRING, .value.str.len = strlen(demo_reason_string), .value.str.value = (uint8_t *)demo_reason_string};
aiot_mqtt_props_add(disconn_props, &reason_prop);
res = aiot_mqtt_disconnect_v5(mqtt_handle, demo_reason_code, disconn_props);
aiot_mqtt_props_deinit(&disconn_props);
}
步骤九:退出程序
调用aiot_mqtt_deinit,销毁MQTT客户端实例,释放资源。
res = aiot_mqtt_deinit(&mqtt_handle);
if (res < STATE_SUCCESS) {
printf("aiot_mqtt_deinit failed: -0x%04X\n", -res);
return -1;
}
后续步骤
运行日志
MQTT 5.0接入功能的例程运行后,您可以在设备端和物联网平台查看日志信息。
前提条件
已配置并运行C Link SDK的MQTT 5.0接入例程。详细信息,请参见使用示例。
设备端日志
您可以在设备端查看运行结果。
- 连接日志。出现如下日志,表示设备与物联网平台连接成功。
[1680608104.988][LK-0313] MQTT user calls aiot_mqtt_connect api, connect [1680608104.988][LK-032A] mqtt host: a18wP******.iot-as-mqtt.cn-shanghai.aliyuncs.com [1680608104.988][LK-0317] user name: LightSwitch&a18wP******* [1680608104.988][LK-0318] password: 4CEB5BA5B334CDB73DAAEEF97EBC1A09******************* success to establish tcp, fd=3 local port: 34624 [1680608104.999][LK-1000] establish mbedtls connection with server(host='a18wP*******.iot-as-mqtt.cn-shanghai.aliyuncs.com', port=[1883]) [1680608105.066][LK-1000] success to establish mbedtls connection, (cost 45329 bytes in total, max used 48297 bytes) [1680608105.099][LK-0000] MQTT_PROP_ID_RECEIVE_MAXIMUM:10 [1680608105.099][LK-0000] MQTT_PROP_ID_TOPIC_ALIAS_MAXIMUM:20 [1680608105.099][LK-0000] MQTT_PROP_ID_MAXIMUM_QOS:1 [1680608105.099][LK-0000] MQTT_PROP_ID_RETAIN_AVAILABLE:1 [1680608105.099][LK-0000] MQTT_PROP_ID_MAXIMUM_PACKET_SIZE:262144 [1680608105.099][LK-0000] MQTT_PROP_ID_WILDCARD_SUBSCRIPTION_AVAILABLE:1 [1680608105.099][LK-0000] MQTT_PROP_ID_SUBSCRIPTION_IDENTIFIERS_AVAILABLE:0 [1680608105.099][LK-0000] MQTT_PROP_ID_SHARED_SUBSCRIPTION_AVAILABLE:1 [1680608105.099][LK-0000] MQTT_PROP_ID_SESSION_EXPIRY_INTERVAL:0 [1680608105.099][LK-0000] MQTT_PROP_ID_SERVER_KEEP_ALIVE:1200 [1680608105.099][LK-0313] MQTT connect success in 116 ms
- 订阅Topic日志。
[1680608105.099][LK-0309] sub: /sys/a18wP******/LightSwitch/thing/event/property/post_reply
- 上报消息日志。
[1680608105.099][LK-0309] pub: /sys/a18wP******/LightSwitch/thing/event/property/post [LK-030A] > 7B 22 69 64 22 3A 22 31 22 2C 22 76 65 72 73 69 | {"id":"1","versi [LK-030A] > 6F 6E 22 3A 22 31 2E 30 22 2C 22 70 61 72 61 6D | on":"1.0","param [LK-030A] > 73 22 3A 7B 22 4C 69 67 68 74 53 77 69 74 63 68 | s":{"LightSwitch [LK-030A] > 22 3A 30 7D 7D
物联网平台日志
您可以在物联网平台控制台,查看设备的状态和运行日志。
- 在线状态:在左侧导航栏,选择设备管理 > 设备,找到设备,查看设备状态。设备状态显示为在线,则表示设备与物联网平台成功连接。
- 运行日志:在左侧导航栏,选择监控运维 > 日志服务,选择产品后,查看设备上线、订阅Topic和上报消息的日志。
后续步骤
运行日志中出现的错误信息,请参见常见错误码,根据提示解决问题。
本文介绍在配置C Link SDK的设备接入功能时,常见错误。
Link SDK通过以下两种渠道,表达建连失败时的内部运行状态。您可以通过内部运行状态,了解失败原因。
- API的返回值是
int32_t
的非正数整型,也叫状态码,状态码返回0
表成功,其它值表示运行状态 。- 使用
retval = aiot_xxx_yyy()
方式获取返回值。 - 所有返回值唯一对应内部运行分支,详情请参见
aiot_state_api.h
或aiot_xxx_api.h
。 - 所有组件返回值的值域互不重叠,共同分别分布在
0x0000 - 0xFFFF
。
- 使用
- 从SDK内部,调用您的日志回调函数。
以下为常见错误码,完整的错误码列表,请参见aiot_state_api.h。
MQTT接入
错误码 | 说明 |
STATE_MQTT_CONNACK_RCODE_SERVER_UNAVAILABLE | MQTT服务器拒绝提供连接, 服务当前不可用。请稍后重试。 |
STATE_MQTT_CONNACK_RCODE_BAD_USERNAME_PASSWORD | 连接时的用户名或密码非法。 |
STATE_MQTT_CONNACK_RCODE_NOT_AUTHORIZED | MQTT服务器进行连接身份验证失败,登录密码错误。请检查设备认证信息是否正确。 |
HTTPS接入
错误码 | 说明 |
STATE_HTTP_STATUS_LINE_INVALID | 解析收到的HTTPS报文时,无法获取有效的关于状态的代码行。无法获取HTTPS StatusCode 。 |
STATE_HTTP_READ_BODY_FINISHED | 解析收到的HTTPS报文时,报文的Body部分已接收完毕,但没有更多数据。 |
STATE_HTTP_AUTH_CODE_FAILED | HTTPS认证应答的StatusCode不是200,认证失败。请检查认证签名是否正确。 |
STATE_HTTP_AUTH_NOT_FINISHED | 未完成接收HTTPS认证应答接,认证失败。 |
STATE_HTTP_AUTH_TOKEN_FAILED | HTTPS认证应答中,未能解析到Token,认证失败。 |
网络层
错误码 | 说明 |
STATE_PORT_NETWORK_DNS_FAILED | TCP域名解析失败,请检查域名或IP是否正确。 |
STATE_PORT_NETWORK_CONNECT_FAILED | TCP建立连接失败。 |
STATE_PORT_TLS_INVALID_MAX_FRAGMENT | TLS报文最大长度设置为0,该设置非法,请检查后重新设置。 |
STATE_PORT_TLS_INVALID_SERVER_CERT | TLS服务端证书配置错误,请检查服务端证书是否正确。 |
STATE_PORT_TLS_INVALID_CLIENT_CERT | TLS设备端证书配置错误,请检查客户端证书是否正确。 |
STATE_PORT_TLS_INVALID_CLIENT_KEY | TLS客户端密钥配置错误,请检查客户端密钥是否正确。 |
STATE_PORT_TLS_DNS_FAILED | TLS域名解析失败,请检查域名或IP是否配置正确。 |
STATE_PORT_TLS_SOCKET_CREATE_FAILED | TLS Socket创建失败。 |
STATE_PORT_TLS_SOCKET_CONNECT_FAILED | TLS Socket连接失败。 |
STATE_PORT_TLS_INVALID_RECORD | SSL收到的数据包出错,请检查TLS帧数据的长度是否过小。 |