前言
这节着重说一下如何把源码中的MQTT底层包移植到用户自己的工程
这节代码只是讲解详细流程,并不可以使用
准备一个空的工程
1.注:请自行准备一个已经可以实现TCP连接的工程
由于用的网络芯片不一样,连接方式不一样,本人就在工程中假设连接了TCP
2.把以下文件放入自己的工程
添加一个文件夹
添加文件
添加MQTT文件中的所有文件
添加头文件路径
包含mqtt.h 编译下
错误原因
这是两个把数据发送给网络模块的函数
这两个函数需要根据自己的修改
用户需要把数据发送给网络模块的函数放到此处
就是模块作为TCP客户端,把TCP客户端发送数据给TCP服务器数据的函数放在这里
在1ms定时器中放入以下函数
#include "mqtt.h"
mqtt_time_data(&mymqtt);
连接MQTT
1.用一些数组存储连接MQTT的信息
注册连接和断开函数
unsigned char MQTTid[50] = "123456789";//ClientID unsigned char MQTTUserName[20] = "yang";//用户名 unsigned char MQTTPassWord[50] = "11223344";//密码 unsigned char MQTTkeepAlive = 30;//心跳包时间 unsigned char MQTTPublishTopic[30]="1111";//存储MQTT发布的主题 unsigned char MQTTWillMessage[50] = "{\"data\":\"status\",\"status\":\"offline\"}";//遗嘱消息 unsigned char MQTTWillQos = 0;//消息等级 unsigned char MQTTWillRetained = 1;//是否需要服务器记录
/**连接上MQTT回调函数 * @brief 连接上MQTT回调函数 * @param None * @retval None * @warning None * @example **/ void MqttConnect() { } /**MQTT断开连接回调 * @brief MQTT断开连接回调 * @param None * @retval None * @warning None * @example **/ void MqttDisConnect() { mqtt_init(&mymqtt); }
mqtt_init(&mymqtt); mqtt_connect_reg(&mymqtt,MqttConnect);//注册连接回调函数 mqtt_disconnect_reg(&mymqtt,MqttDisConnect);//注册断开连接回调函数
注:如果不想使用遗嘱,可自行屏蔽
2.实现具体的连接
用户先用自己的模块用TCP连接上TCP服务器(MQTT服务器)
然后发送连接MQTT指令
最后判断下是否连接成功
int len;//获取数据长度 unsigned char *str;//打包的数据首地址 char ConnectedMqttFlag;//1:连接上MQTT 0:未连接
if(ConnectedMqttFlag == 0){//没有连接上MQTT //用户先自行控制模块以TCP方式连接上MQTT服务器 //发送连接MQTT的指令 mymqtt.mqtt_connect_info.client_id = MQTTid;//client_id mymqtt.mqtt_connect_info.keepalive = MQTTkeepAlive;//心跳包时间 mymqtt.mqtt_connect_info.username = MQTTUserName;//用户名 mymqtt.mqtt_connect_info.password = MQTTPassWord;///密码 mymqtt.mqtt_connect_info.will_topic = MQTTPublishTopic;//遗嘱发布的主题 mymqtt.mqtt_connect_info.will_message = MQTTWillMessage;//遗嘱的消息 mymqtt.mqtt_connect_info.will_qos = MQTTWillQos;//遗嘱的消息等级 mymqtt.mqtt_connect_info.will_retain = MQTTWillRetained;//是否需要服务器保留消息 mymqtt.mqtt_connect_info.clean_session = 1;//清除连接信息 len = mqtt_connect(&mymqtt,&str);//打包连接信息 //打包的数据首地址 str 数据长度:len if(len>0){ UsartOutStr(str,len);//发送MQTT协议数据给网络模块,其实就是TCP客户端发送数据给服务器(请根据自己的替换) } //发送完连接指令以后,MQTT服务器会返回连接信息,请按照下面程序处理信息 //判断模块是否连接上,假设模块返回的数据存入了Usart1ReadBuff数组 if(mqtt_connect_ack(Usart1ReadBuff)==0)//连接上了MQTT { ConnectedMqttFlag = 1;//连接上MQTT if(mymqtt.connectCb){//调用连接回调函数 mymqtt.connectCb(); } } }
3.如果断开连接,需要让模块重新连接MQTT,请在断开连接回调函数中
ConnectedMqttFlag=0;//断开连接以后,重新配置模块连接
接收处理通信过程中的各种数据
1.后期的通信都是利用数据缓存实现,请先添加以下程序
if(ConnectedMqttFlag)//配置模块成功(模块连接了MQTT) { mqtt_send_function(&mymqtt);//提取发送缓存的MQTT协议 mqtt_keep_alive(&mymqtt);//处理发送心跳包 //网络模块接收到了数据 if(1)//此处请根据自己的网络模块自行修改 { //假设网络接收到的数据:Usart1ReadBuff 数据长度:Usart1ReadCntCopy mqtt_read_function(&mymqtt,Usart1ReadBuff,Usart1ReadCntCopy); } }
2.注册接收数据函数
/** * @brief MQTT接收数据回调 * @param topic:主题 * @param topic_len:主题长度 * @param data:接收的数据 * @param lengh:接收的数据长度 * @retval None * @warning None * @example **/ void MqttReceive(const char* topic, uint32_t topic_len,const char *data, uint32_t lengh)//接收到数据回调 { }
mqtt_received_reg(&mymqtt,MqttReceive);//注册接收数据回调函数
订阅主题
1.一般可以在连接成功回调函数里面订阅主题
当然只要连接上以后,可以在程序的任何地方执行订阅函数
unsigned char MQTTSubscribeTopic[30]="2222";//存储MQTT订阅的主题
/**订阅主题成功 * @brief 订阅主题成功 * @param None * @retval None * @warning None * @example **/ void subscribedCb(int pdata) { } /**订阅主题失败 * @brief 订阅主题失败 * @param None * @retval None * @warning None * @example **/ void failsubscribedCb(int pdata) { }
mqtt_subscribe(&mymqtt, MQTTSubscribeTopic,0,subscribedCb,failsubscribedCb);//订阅主题
订阅的消息等级支持0,1,2
mqtt_subscribe(&mymqtt, MQTTSubscribeTopic,0,subscribedCb,failsubscribedCb);
mqtt_subscribe(&mymqtt, MQTTSubscribeTopic,1,subscribedCb,failsubscribedCb);
mqtt_subscribe(&mymqtt, MQTTSubscribeTopic,2,subscribedCb,failsubscribedCb);
发布消息
1.列如:把接收的消息发布出去
/** * @brief 发布成功 * @param None * @retval None * @warning None * @example **/ void PublishedCb() { } /** * @brief MQTT接收数据回调 * @param topic:主题 * @param topic_len:主题长度 * @param data:接收的数据 * @param lengh:接收的数据长度 * @retval None * @warning None * @example **/ void MqttReceive(const char* topic, uint32_t topic_len,const char *data, uint32_t lengh)//接收到数据回调 { mqtt_publish(&mymqtt,MQTTPublishTopic,(unsigned char*)data,topic_len, 0, 1,PublishedCb);//发布消息 }
提示:只有发布的消息等级是1/2的时候,服务器才会有应答信息
所以只有1/2的时候才会进入发布成功回调函数