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接口说明

  1. 网络接口初始化

函数

void NewNetwork(Network *n)

描述

网络接口初始化

参数

n:Network结构体指针

返回值

void

  1. 客户端初始化

函数

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

  1. 网络层连接

函数

int ConnectNetwork(Network *n, char *addr, int port)

描述

网络层连接

参数

n:Network结构体指针; addr:MQTT服务器地址; port:MQTT服务器端口;

返回值

0:成功 其他:失败

  1. MQTT协议层连接

函数

int MQTTConnect(Client *c, MQTTPacket_connectData *options)

描述

MQTT协议层连接

参数

c:Client结构体指针; options:连接参数 ;

返回值

0:成功 其他:失败

  1. 主题订阅

函数

int MQTTSubscribe(Client *c, const char *topicFilter, enum QoS qos, messageHandler messageHandler)

描述

向MQTT服务器订阅主题

参数

c:Client结构体指针; topicFilter:订阅的主题; qos:订阅的服务质量等级; messageHandler:接收回调,当订阅的主题有信息下发时,在这里接收;

返回值

0:成功 其他:失败

  1. 取消订阅的主题

函数

int MQTTUnsubscribe(Client *c, const char *topicFilter);

描述

向MQTT服务器取消订阅的主题

参数

c:Client结构体指针; topicFilter:想要取消的主题;

返回值

0:成功 其他:失败

  1. 发布消息

函数

int MQTTPublish(Client *c, const char *topicName, MQTTMessage *message)

描述

发布消息

参数

c:Client结构体指针; topicFilter:消息发布主题; message:需要发布的消息;

返回值

0:成功 其他:失败

  1. 断开MQTT协议层连接

函数

int MQTTDisconnect(Client *c)

描述

断开MQTT协议层连接

参数

c:Client结构体指针; (注意:该接口调用后只是断开MQTT协议层的连接)

返回值

0:成功 其他:失败

  1. 阻塞等待数据接收

函数

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程序配置。