位置导航: 首页 / 零基础入门学用物联网总目录 / MQTT篇目录 /本页
在本节课里,我们将使用ESP8266配合MQTTfx客户端软件,通过实际操作来看一下MQTT的QoS是如何发挥作用的。
在开始本节课以前请确保您的电脑已经成功安装了MQTTfx软件。另外我们还将使用PubSubClient库。您可以通过以下链接获取此库。
官网地址:https://pubsubclient.knolleary.net/
GitHub:https://github.com/knolleary/pubsubclient/
百度网盘下载: https://pan.baidu.com/s/12MHGbdfiOdwOGip5RMSSEQ 提取码: sizy
当您将PubSubClient库安装后,我们就可以使用该库进行开发了。假如您不知道如何安装该库,可以参考本站的这篇教程文章。
PubSubClient库目前只支持1级QoS订阅,因此我们将仅介绍如何使用ESP8266接收QoS=1的MQTT消息。
使用ESP8266接收QoS=1的MQTT消息
要使用QoS=1订阅MQTT消息,需要满足以下要求:
1 接收端要有确定的clientID
2 接收端连接服务器时 cleanSession=False
3 发送端发布消息时 QoS=1或QoS=2
4 接收端订阅消息时 QoS=1
以下是ESP8266订阅QoS=1消息的示例程序。您可以将此程序上传ESP8266开发板并且通过以下步骤测试ESP8166开发板QoS=1的订阅情况。
– 在此程序控制下,ESP8266启动后将会尝试连接MQTT服务端。
连接时cleanSession=false。
– 接下来ESP8266在订阅主题时,将QoS设置为1。
– 保持ESP8266在线,使用MQTTfx向ESP8266所订阅的主题发布QoS=1的信息。
– ESP8266将会收到信息(至此还没有体现QoS=1的优势)
– 将ESP8266断电,然后再次使用MQTTfx向ESP8266订阅主题发布QoS=1的信息。
此时由于ESP8266未通电,所以无法接收到MQTTfx发送的信息。因此MQTT服务端
将会保存此信息。
– 将ESP8266再次通电,ESP8266连接到MQTT服务端后,将会马上收到了MQTTfx在ESP8266断电时所发送的信息。(这就是QoS=1的优势,即客户端断电再通电后依然可以收到QoS=1信息。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
/********************************************************************** 项目名称/Project : 零基础入门学用物联网 程序名称/Program name : subscribe_qos1 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com) 作者/Author : CYNO朔 日期/Date(YYYYMMDD) : 20200813 程序目的/Purpose : 本程序旨在演示如何使用PubSubClient库使用ESP8266向MQTT服务器订阅信息。 订阅QoS级别为1。 - 在此程序控制下,ESP8266启动后将会尝试连接MQTT服务端。 连接时cleanSession=false。 - 接下来ESP8266在订阅主题时,将QoS设置为1。 - 保持ESP8266在线,使用MQTTfx向ESP8266所订阅的主题发布QoS=1的信息。 - ESP8266将会收到信息(至此还没有体现QoS=1的优势) - 将ESP8266断电,然后再次使用MQTTfx向ESP8266订阅主题发布QoS=1的信息。 此时由于ESP8266未通电,所以无法接收到MQTTfx发送的信息。因此MQTT服务端 将会保存此信息。 - 将ESP8266再次通电,ESP8266连接到MQTT服务端后,将会马上收到了MQTTfx在ESP8266断电时所发送的信息。(这就是QoS=1的优势,即客户端断电再通电后依然可以收到QoS=1信息。) 要使用QoS=1订阅MQTT消息,需要满足以下要求: 1 接收端要有确定的clientID 2 接收端连接服务器时 cleanSession=False 3 发送端发布消息时 QoS=1或QoS=2 4 接收端订阅消息时 QoS=1 ----------------------------------------------------------------------- 本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。 该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/ ***********************************************************************/ #include <ESP8266WiFi.h> #include <PubSubClient.h> // 设置wifi接入信息(请根据您的WiFi信息进行修改) const char* ssid = "taichi-maker"; const char* password = "12345678"; const char* mqttServer = "test.ranye-iot.net"; // 如以上MQTT服务器无法正常连接,请前往以下页面寻找解决方案 // http://www.taichi-maker.com/public-mqtt-broker/ WiFiClient wifiClient; PubSubClient mqttClient(wifiClient); const int subQoS = 1; // 客户端订阅主题时使用的QoS级别(截止2020-10-07,仅支持QoS = 1,不支持QoS = 2) const bool cleanSession = false; // 清除会话(如QoS>0必须要设为false) const char* willTopic = "willTopic"; // 遗嘱主题名称 const char* willMsg = "willMsg"; // 遗嘱主题信息 const int willQos = 0; // 遗嘱QoS const int willRetain = false; // 遗嘱保留 void setup() { pinMode(LED_BUILTIN, OUTPUT); // 设置板上LED引脚为输出模式 digitalWrite(LED_BUILTIN, HIGH); // 启动后关闭板上LED Serial.begin(9600); // 启动串口通讯 //设置ESP8266工作模式为无线终端模式 WiFi.mode(WIFI_STA); // 连接WiFi connectWifi(); // 设置MQTT服务器和端口号 mqttClient.setServer(mqttServer, 1883); mqttClient.setCallback(receiveCallback); // 连接MQTT服务器 connectMQTTserver(); } void loop() { // 如果开发板未能成功连接服务器,则尝试连接服务器 if (!mqttClient.connected()) { connectMQTTserver(); } // 处理信息以及心跳 mqttClient.loop(); } // 连接MQTT服务器并订阅信息 void connectMQTTserver(){ // 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名) String clientId = "client-" + WiFi.macAddress(); /* 连接MQTT服务器 boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage, boolean cleanSession); 若让设备在离线时仍然能够让qos1工作,则connect时的cleanSession需要设置为false */ if (mqttClient.connect(clientId.c_str(), NULL, NULL, willTopic, willQos, willRetain, willMsg, cleanSession)) { Serial.print("MQTT Server Connected. ClientId: "); Serial.println(clientId); subscribeTopic(); // 订阅指定主题 } else { Serial.print("MQTT Server Connect Failed. Client State:"); Serial.println(mqttClient.state()); delay(5000); } } // 收到信息后的回调函数 void receiveCallback(char* topic, byte* payload, unsigned int length) { Serial.print("Message Received ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(""); Serial.print("Message Length(Bytes) "); Serial.println(length); if ((char)payload[0] == '1') { // 如果收到的信息以“1”为开始 digitalWrite(BUILTIN_LED, LOW); // 则点亮LED。 } else { digitalWrite(BUILTIN_LED, HIGH); // 否则熄灭LED。 } } // 订阅指定主题 void subscribeTopic(){ // 建立订阅主题。主题名称以Taichi-Maker-Sub为前缀,后面添加设备的MAC地址。 // 这么做是为确保不同设备使用同一个MQTT服务器测试消息订阅时,所订阅的主题名称不同 String topicString = "Taichi-Maker-Sub-" + WiFi.macAddress(); char subTopic[topicString.length() + 1]; strcpy(subTopic, topicString.c_str()); // 通过串口监视器输出是否成功订阅主题以及订阅的主题名称 // 请注意subscribe函数第二个参数数字为QoS级别。这里为QoS = 1 if(mqttClient.subscribe(subTopic, subQoS)){ Serial.print("Subscribed Topic: "); Serial.println(subTopic); } else { Serial.print("Subscribe Fail..."); } } // ESP8266连接wifi void connectWifi(){ WiFi.begin(ssid, password); //等待WiFi连接,成功连接后输出成功信息 while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.print("."); } Serial.println(""); Serial.println("WiFi Connected!"); Serial.println(""); } |