12-MQTT介绍

2018-12-12 16:04:04 浏览数 (1)

看到这个项目第一想法肯定需要一个服务器,所有的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,后期如果真的需要研究了,再研究

也不迟,现在就是先学会用

0 人点赞