引子:很久以前就知道MQTT协议了,也知道该协议主要应用到物联网上,具备很多特点,但是一直是处于不知其意状态。今天有幸看到了一篇博文,然后自己将该博文里面的内容操作了一遍,同时将手上的CC3200开发板连接到CloudMQTT代理服务器上,以CC3200为客户端,订阅三个主题(控制三个LED灯),发布两个主题(按键SW2,SW3)。当然这也是有参考文献的,很久之前就做过实验,不过那时都是似懂非懂,今天重新理了一下,感觉大快人心。
参考博文:
1.MQTT学习笔记——MQTT协议体验 Mosquitto安装和使用
2.一步一步学习CC3200与MQTT服务器通讯
通过第一篇博文,可以直观的理解MQTT协议的通信模型,如图1所示:
图1:MQTT模型
这是一个很具体的应用模型,从中可以发现,整个框架中有三个角色:
服务器代理,订阅者,发布者。
在应用过程中:1、服务器代理首先搭好桥,供接下来的二者使用。2、订阅者向服务器进行主题订阅。3,发布者开始想服务器发布订阅者预定的主题消息。
注意,1必须先操作,否则后面两步无法执行。2,3谁先操作没关系,一般来说先操作2。就像从水库里接水一样,先准备好水桶再开龙头。
接下来是在操作中的截图,我在图片中进行了相关的解释。
图2是当发布者发布消息后,MQTT协议的执行过程。
图2
图3为订阅者订阅主题,发布者发布主题,这二者与服务器的交互信息。
图3
进行完上面的试验后,会找到了一点感觉,趁热打铁,使用CC3200进行试验,同时去看代码是如何实现的。
本实验中,将CC3200作为客户端,注意客户端既可以发布消息,也可以订阅消息。使用 CloudMQTT作为服务器代理,在使用它之前,需要进行先关的申请注册,得到相关信息,如图4
图4
相关的数据在代码中会使用到。这里具体如何更改代码不做详细讲解,很简单,根据提供的参考博文可以完成。我们这里主要看代码是如何实现发布,订阅功能的。其实这个过程,就是将上面第一个实验的过程用代码实现。
首先看代码中的宏定义:
#define SERVER_ADDRESS
"m13.cloudmqtt.com"
//#define PORT_NUMBER 1883
#define PORT_NUMBER 17020
#define MAX_BROKER_CONN 1
#define SERVER_MODE MQTT_3_1
/*Specifying Receive time out for the Receive task*/
#define RCV_TIMEOUT 30
/*Background receive task priority*/
#define TASK_PRIORITY 3
/* Keep Alive Timer value*/
#define KEEP_ALIVE_TIMER 25
/*Clean session flag*/
#define CLEAN_SESSION true
/*Retain Flag. Used in publish message. */
#define RETAIN 1
/*Defining
Publish Topic*/
#define PUB_TOPIC_FOR_SW3 "/cc3200/ButtonPressEvtSw3"
#define PUB_TOPIC_FOR_SW2 "/cc3200/ButtonPressEvtSw2"
/*Defining Number of topics*/
#define TOPIC_COUNT 3
/*Defining
Subscription Topic Values*/
#define TOPIC1 "/cc3200/ToggleLEDCmdL1"
#define TOPIC2 "/cc3200/ToggleLEDCmdL2"
#define TOPIC3 "/cc3200/ToggleLEDCmdL3"
/*Defining QOS levels*/
#define QOS0 0
#define QOS1 1
#define QOS2 2
上面定义了发布和订阅的主题,其他的参数,如QOS,可以看MQTT手册,这个时候去看手册,会轻松点。
下面是
作为客户端连接服务器代理的代码:
connect_config usr_connect_config[] =
{
{
{
{
SL_MQTT_NETCONN_URL,
SERVER_ADDRESS,
PORT_NUMBER,
0,
0,
0,
NULL
},
SERVER_MODE,
true,
},
NULL,
"user1",
//NULL,
//NULL,
"
User",
"
Password",
true,
KEEP_ALIVE_TIMER,
{Mqtt_Recv, sl_MqttEvt, sl_MqttDisconnect},//huidiaohuanshu
TOPIC_COUNT,
{TOPIC1, TOPIC2, TOPIC3},
{QOS2, QOS2, QOS2},
{WILL_TOPIC,WILL_MSG,WILL_QOS,WILL_RETAIN},
false
}
最后看下主要的功能函数,具体代码不看,主要说下其功能。
1、Mqtt_Recv(void *app_hndl, const char *topstr, long top_len, const void *payload,
long pay_len, bool dup,unsigned char qos, bool retain);//cc3200作为客户端的接受函数,该函数内,会对接受的消息进行处理,来触发函数5,以实现控制LED的功能。
2、static void sl_MqttDisconnect(void *app_hndl); //断开连接
3、void pushButtonInterruptHandler2(); //函数3,4都是CC3200按键时,进行发布的触发函数
4、void pushButtonInterruptHandler3();
5、void ToggleLedState(ledEnum LedNum);//led 处理函数
6、void TimerPeriodicIntHandler(void); ?//心跳函数,当服务器代码没有收到发布者和订阅者的消息时,服务器会与客户端会维持心跳连接
7、void MqttClient(void *pvParameters);//客户端程序,此程序功能为:
1. Initializes network driver and connects to the default AP
2. Initializes the mqtt library and set up MQTT connection configurations
3. set up the button events and their callbacks(for publishing)
4. handles the callback signals
现在展现实验结果(图5):
图5
可以看到,在web上发送/cc3200/ToggleLEDCmdL1 时,CC3200接到消息,并且LED1状态翻转。(当然你看不到,哈)
以上是MQTT协议应用的初步收获,这个经历激起了我的兴趣,希望你也是。
拓展阅读: http://www.hivemq.com/blog/mqtt-essentials-part-4-mqtt-publish-subscribe-unsubscribe