看到这个项目第一想法肯定需要一个服务器,所有的wifi设备和手机都去连接这个服务器,然后服务器进行信息的中转
这个服务器呢第一种方式是自己开发
就变成了
其实MQTT的基本功能就是上面的
还要说一点MQTT实质上就是个TCP服务器
然后在TCP的基础上封装了一套协议
只要大家的设备支持TCP,也就可以自己写封装函数,然后实现MQTT功能
现在说一下两个设备是如何通信的
假设设备1 先连接MQTT服务器 然后告诉MQTT服务器它接收标志是1111的消息
假设设备2 先连接MQTT服务器 然后告诉MQTT服务器它接收标志是2222的消息
然后设备1 , 发送消息的时候 , 消息的开头写上标志 2222 然后后面跟上数据, 服务器收到以后就转发给接收标志是2222的设备 ,这样设备2就接收到了设备1的数据
然后设备2 , 发送消息的时候 , 消息的开头写上标志 1111 然后后面跟上数据, 服务器收到以后就转发给接收标志是1111的设备 ,这样设备1就接收到了设备2的数据
其实具体的协议呢看下面, 这是我用单片机写的MQTT封包,就是在网络芯片实现TCP的基础上让芯片连接MQTT服务器,然后实现通信
代码语言:javascript复制/**
* @brief 连接服务器的打包函数
* @param
* @retval
* @example
**/
char ConnectMqtt(char *ClientID,char *Username,char *Password)
{
int ClientIDLen = strlen(ClientID);
int UsernameLen = strlen(Username);
int PasswordLen = strlen(Password);
int DataLen = 0;
int Index = 2;
int i = 0;
DataLen = 12 2 2 ClientIDLen UsernameLen PasswordLen;
MqttSendData[0] = 0x10; //MQTT Message Type CONNECT
MqttSendData[1] = DataLen; //剩余长度(不包括固定头部)
MqttSendData[Index ] = 0; // Protocol Name Length MSB
MqttSendData[Index ] = 4; // Protocol Name Length LSB
MqttSendData[Index ] = 'M'; // ASCII Code for M
MqttSendData[Index ] = 'Q'; // ASCII Code for Q
MqttSendData[Index ] = 'T'; // ASCII Code for T
MqttSendData[Index ] = 'T'; // ASCII Code for T
MqttSendData[Index ] = 4; // MQTT Protocol version = 4
MqttSendData[Index ] = 0xc2; // conn flags
MqttSendData[Index ] = 0; // Keep-alive Time Length MSB
MqttSendData[Index ] = 60; // Keep-alive Time Length LSB 60S心跳包
MqttSendData[Index ] = (0xff00&ClientIDLen)>>8;// Client ID length MSB
MqttSendData[Index ] = 0xff&ClientIDLen; // Client ID length LSB
for(i = 0; i < ClientIDLen; i )
{
MqttSendData[Index i] = ClientID[i];
}
Index = Index ClientIDLen;
if(UsernameLen > 0)
{
MqttSendData[Index ] = (0xff00&UsernameLen)>>8;//username length MSB
MqttSendData[Index ] = 0xff&UsernameLen; //username length LSB
for(i = 0; i < UsernameLen ; i )
{
MqttSendData[Index i] = Username[i];
}
Index = Index UsernameLen;
}
if(PasswordLen > 0)
{
MqttSendData[Index ] = (0xff00&PasswordLen)>>8;//password length MSB
MqttSendData[Index ] = 0xff&PasswordLen; //password length LSB
for(i = 0; i < PasswordLen ; i )
{
MqttSendData[Index i] = Password[i];
}
Index = Index PasswordLen;
}
return Index;
}
/**
* @brief MQTT订阅/取消订阅数据打包函数
* @param SendData
* @param topic 主题
* @param qos 消息等级
* @param whether 订阅/取消订阅请求包
* @retval
* @example
**/
char MqttSubscribeTopic(char *topic,char qos,char whether)
{
Index = 0;
i = 0;
if(whether)
MqttSendData[Index ] = 0x82; //0x82 //消息类型和标志 SUBSCRIBE 订阅
else
MqttSendData[Index ] = 0xA2; //0xA2 取消订阅
MqttSendData[Index ] = strlen(topic) 5; //剩余长度(不包括固定头部)
MqttSendData[Index ] = 0; //消息标识符,高位
MqttSendData[Index ] = 0x01; //消息标识符,低位
MqttSendData[Index ] = (0xff00&strlen(topic))>>8; //主题长度(高位在前,低位在后)
MqttSendData[Index ] = 0xff&strlen(topic); //主题长度
for (i = 0;i < strlen(topic); i )
{
MqttSendData[Index i] = topic[i];
}
Index = Index strlen(topic);
if(whether)
{
MqttSendData[Index] = qos;//QoS级别
Index ;
}
return Index;
}
/**
* @brief MQTT发布数据打包函数
* @param mqtt_message
* @param topic 主题
* @param qos 消息等级
* @retval
* @example
**/
char MqttPublishData(char * topic, char * message,char length, char qos)
{
char topic_length = strlen(topic);
char message_length = length;
char i,index=0;
static char id=0;
MqttSendData[index ] = 0x30; // MQTT Message Type PUBLISH
if(qos)
MqttSendData[index ] = 2 topic_length 2 message_length;//数据长度
else
MqttSendData[index ] = 2 topic_length message_length; // Remaining length
MqttSendData[index ] = (0xff00&topic_length)>>8;//主题长度
MqttSendData[index ] = 0xff&topic_length;
for(i = 0; i < topic_length; i )
{
MqttSendData[index i] = topic[i];//拷贝主题
}
index = topic_length;
if(qos)
{
MqttSendData[index ] = (0xff00&id)>>8;
MqttSendData[index ] = 0xff&id;
id ;
}
for(i = 0; i < message_length; i )
{
MqttSendData[index i] = message[i];//拷贝数据
}
index = message_length;
return index;
}
https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.8a931debd5LqD6&id=582060294154
当然啦,咱现在用的WIFI和GPRS里面已经写好了这种组合包,咱直接调用API就可以了
其实大家不需要去研究这个协议,最起码现在不需要,我只是让大家稍微了解下MQTT,后期如果真的需要研究了,再研究
也不迟,现在就是先学会用