MQTT是一種基於TCP/IP協議棧構建的異步通信協議,是一種輕量級的發佈/訂閱信息傳輸協議,基於topic訂閱關係的發佈和推送;在實踐中可空間上,將消息發送者和接受者分離,可以再不可靠的網絡環境中進行擴展,適用於設備硬件存儲空間有限或網絡帶寬有限的場景。
上面是比較官方的解釋,那麼我們用我們聽得懂的話來解釋,現在的抖音很火,那我們就用抖音舉個栗子:
抖音是一個短視頻平臺,任何人都可以發佈自己拍的視頻,也可以看別人的視頻,那麼我們假設有用戶A和用戶B;
用戶A ------關注------> 用戶B
用戶B ---沒有關注---> 用戶A
那麼就會出現下面的情況:
用戶A發送視頻 ----不會推送----> 用戶B
用戶B發送視頻 -------推送-------> 用戶A
也就是說,用戶B沒有關注用戶A,所以當用戶A發佈視頻後,用戶B是不會接收到用戶A的視頻的;
反之,用戶B發佈視頻後,用戶A會第一時間接收到;
那麼,用戶A爲什麼會第一時間接受到呢?
這是因爲有抖音的服務器作爲中間人,當存在訂閱(關注)關係後,當用戶B發送數據後,服務器會將數據推送給所有訂閱(關注)的用戶;MQTT就是這樣基於topic訂閱關係進行發佈和推送的!
一、MQTT協議的元素
-
MQTT協議的角色:在MQTT中,就有三個角色,發佈者、服務器和訂閱者;
-
MQTT協議的主題:在MQTT中,主題可以理解成是發佈者,即一個主題我可以發送多條信息,所有訂閱了這個主題的用戶,都可以接收到該主題信息;
-
MQTT協議的消息:在MQTT中,就可以理解成發佈者發佈的內容,當訂閱者接收到信息後,就可以對信息進行處理;
-
那麼服務器在哪裏體現呢?
首先,每臺主機都可以當做服務端和客戶端,即都可以發佈信息和接受信息;
其次,一臺主機可以發佈或訂閱多個主題的信息;
二、樹莓派上安裝Mosquitto
# 安裝mosquitto服務
apt-get install mosquitto
# 安裝mosquitto工具
apt-get install mosquitto-clients
三、啓動Mosquitto服務
mosquitto -v
出現上面的信息,那就證明mosquitto服務已經安裝成功,並且服務已經啓動了,端口爲1883;
四、訂閱消息
mosquitto_sub -v -t test -h 10.168.1.193
# mosquitto_sub -v -t 主題 -h 地址
五、發佈消息
mosquitto_pub -t test -h 10.168.1.193 -m "hello"
# mosquitto_pub -t 主題 -h 地址 -m 消息內容
六、使用Python來接受並處理數據
- 安裝Python MQTT庫
pip install paho-mqtt
- 框架代碼解釋
# -*- coding: utf-8 -*- import paho.mqtt.client as mqtt # 導入mqtt庫 # 連接成功回調函數 def on_connect(client, userdata, flags, rc): print("Connected with result code " + str(rc)) client.subscribe("mqtt_ttt") # 這裏即爲訂閱的主題 # client.subscribe("mqtt_ttt") 這裏可以訂閱多個主題 # 消息推送回調函數 def on_message(client, userdata, msg): print(str(msg.topic),str(msg.payload)) # 這裏需要注意的是,如果想要對接收到的數據進行處理,那麼要轉換成str類型 # msg.topic 主題名 # msg.payload 接收的信息 if __name__ == '__main__': client = mqtt.Client() # 創建mqtt對象 client.on_connect = on_connect # 設置連接成功的回調函數 client.on_message = on_message # 設置接收到信息後的回調函數 try: client.connect("10.168.1.193", 1883, 60) # 創建連接 client.loop_forever() # 保持監測狀態 except KeyboardInterrupt: client.disconnect() # 斷開連接
- 使用MQTT控制樹莓派GPIO
# -*- coding: utf-8 -*- import paho.mqtt.client as mqtt import json import RPi.GPIO as GPIO GPIO.setmode(GPIO.BOARD) GPIO.setup(16,GPIO.OUT) def on_connect(client, userdata, flags, rc): print("Connected with result code " + str(rc)) client.subscribe("mqtt_ttt") # 消息推送回調函數 def on_message(client, userdata, msg): st = json.loads(msg.payload) # 這裏用json對數據進行處理,方便後面對數據的解析 # 還有一個原因是,我直接對數據進行判斷,會出現問題,至今沒有解決 print(st) # 輸出解析後的數據 # 對數據進行判斷和處理 if st['dt'] == 1: GPIO.output(16,GPIO.HIGH) elif st['dt'] == 0: GPIO.output(16,GPIO.LOW) else: print('err') if __name__ == '__main__': client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message try: client.connect("10.168.1.193", 1883, 60) client.loop_forever() except KeyboardInterrupt: client.disconnect() GPIO.output(16,GPIO.LOW) GPIO.cleanup()