8.3. MQTT CLIENT
8.3.1. 概述
MQTT 是轻量级的发布/订阅消息协议
8.3.2. DEMO工程
apps/demo/demo_DevKitBoard
8.3.3. MQTT示例
示例说明
通过MQTT 协议连接阿里云服务器,并向阿里云订阅主题和发布消息
MQTT流程
1.mqtt参数初始化
unsigned char sendbuf[80], readbuf[80]; MQTTClient client; Network network; MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer; NetworkInit(&network); MQTTClientInit(&client, &network, 30000, sendbuf, sizeof(sendbuf), readbuf, sizeof(readbuf));
2.mqtt网络层连接
char* address = "iot.eclipse.org"; if ((rc = NetworkConnect(&network, address, 1883)) != 0) printf("Return code from network connect is %d\n", rc);
3.mqtt协议层连接
connectData.MQTTVersion = 3; connectData.clientID.cstring = "FreeRTOS_sample"; if ((rc = MQTTConnect(&client, &connectData)) != 0) printf("Return code from MQTT connect is %d\n", rc); else printf("MQTT Connected\n");
4.主题订阅(可选)
void messageArrived(MessageData* data) { printf("Message arrived on topic %.*s: %.*s\n", data->topicName->lenstring.len, data->topicName->lenstring.data, data->message->payloadlen, data->message->payload); } if ((rc = MQTTSubscribe(&client, "FreeRTOS/sample/#", 2, messageArrived)) != 0) printf("Return code from MQTT subscribe is %d\n", rc);
5.消息发布(可选)
MQTTMessage message; char payload[30] = "mqtt test!"; message.qos = 1; message.retained = 0; message.payload = payload; message.payloadlen = strlen(payload); if ((rc = MQTTPublish(&client, "FreeRTOS/sample/a", &message)) != 0) printf("Return code from MQTT publish is %d\n", rc);
6.MQTTYield调用
while (1) { if ((rc = MQTTYield(&client, 1000)) != 0) printf("Return code from yield is %d\n", rc); }
MQTT接口说明
网络接口初始化
函数 |
void NewNetwork(Network *n) |
---|---|
描述 |
网络接口初始化 |
参数 |
n:Network结构体指针 |
返回值 |
void |
客户端初始化
函数 |
void MQTTClient(Client *c, Network *network, unsigned int command_timeout_ms, unsigned char *buf, size_t buf_size, unsigned char *readbuf, size_t readbuf_size) |
---|---|
描述 |
客户端初始化 |
参数 |
c:Client结构体指针; network:Network结构体指针; command_timeout_ms:命令超时时间,单位:毫秒; buf:写缓存指针,内存由用户分配; buf_size:写缓存大小; readbuf:读缓存指针,内存由用户分配; readbuf_size:读缓存大小; |
返回值 |
void |
网络层连接
函数 |
|
---|---|
描述 |
网络层连接 |
参数 |
n:Network结构体指针; addr:MQTT服务器地址; port:MQTT服务器端口; |
返回值 |
0:成功 其他:失败 |
MQTT协议层连接
函数 |
|
---|---|
描述 |
MQTT协议层连接 |
参数 |
c:Client结构体指针; options:连接参数 ; |
返回值 |
0:成功 其他:失败 |
主题订阅
函数 |
int MQTTSubscribe(Client *c, const char *topicFilter, enum QoS qos, messageHandler messageHandler) |
---|---|
描述 |
向MQTT服务器订阅主题 |
参数 |
c:Client结构体指针; topicFilter:订阅的主题; qos:订阅的服务质量等级; messageHandler:接收回调,当订阅的主题有信息下发时,在这里接收; |
返回值 |
0:成功 其他:失败 |
取消订阅的主题
函数 |
|
---|---|
描述 |
向MQTT服务器取消订阅的主题 |
参数 |
c:Client结构体指针; topicFilter:想要取消的主题; |
返回值 |
0:成功 其他:失败 |
发布消息
函数 |
int MQTTPublish(Client *c, const char *topicName, MQTTMessage *message) |
---|---|
描述 |
发布消息 |
参数 |
c:Client结构体指针; topicFilter:消息发布主题; message:需要发布的消息; |
返回值 |
0:成功 其他:失败 |
断开MQTT协议层连接
函数 |
int MQTTDisconnect(Client *c) |
---|---|
描述 |
断开MQTT协议层连接 |
参数 |
c:Client结构体指针; (注意:该接口调用后只是断开MQTT协议层的连接) |
返回值 |
0:成功 其他:失败 |
阻塞等待数据接收
函数 |
int MQTTYield(Client *c, int timeout_ms) |
---|---|
描述 |
阻塞等待数据接收 |
参数 |
c:Client结构体指针; timeout_ms: 接收阻塞时间;(注意:该接口需要被循环调用) |
返回值 |
0:成功 其他:失败 |
示例
示例代码见 apps\common\example\network_protocols\mqtt\main.c
, 测试时需要在 apps/demo/demo_DevKitBoard/include/demo_config.h
,开启宏 USE_MQTT_TEST
。
示例流程如下:
示例需要运行在STA模式 (注:如何进行sta和ap切换,请参考 Wi-Fi部分 )
根据在阿里云上创建的设备,设置好address、username、password、subscribeTopic、publishTopic和clientID等信息,配置格式请参考参考文档。
编译工程,烧录镜像,复位启动。
系统启动并成功联网后,可通过串口软件看到打印信息。
8.3.4. 常见问题
如何进行mqtt调试?
答:mqtt无法订阅或发布消息,一般跟连接配置参数设置和格式等有关。 可以借助其他MQTT客户端软件如:MQTT.fx等,先成功连接mqtt服务器并可以进行订阅和发布后,再仿照其参数进行mqtt程序配置。