前言
1、MQTT 简介
《MQTT 协议规范中文版》一书中对 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)进行了描述:
MQTT 是一种基于客户端服务端架构的发布/订阅模式的消息传输协议。它的设计思想是轻巧、开放、 简单、规范,易于实现。这些特点使得它对很多场景来说都是很好的选择,特别是对于受限的环境如机器与机器的通信(M2M)以及物联网环境(IoT)。----MQTT 协议中文版
与 HTTP 协议一样,MQTT 协议也是应用层协议,工作在 TCP/IP 四层模型中的最上层(应用层),构建于 TCP/IP协议上。MQTT 最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。
如今,MQTT 成为了最受欢迎的物联网协议,已广泛应用于车联网、智能家居、即时聊天应用和工业互联网等领域。目前通过 MQTT 协议连接的设备已经过亿,这些都得益于 MQTT 协议为设备提供了稳定、可靠、易用的通信基础。
2、MQTT 的主要特性
MQTT 协议是为工作在低带宽、不可靠网络的远程传感器和控制设备之间的通讯而设计的协议,它具 有以下主要的几项特性:
①、使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合。
②、基于 TCP/IP 提供网络连接。主流的 MQTT 是基于 TCP 连接进行数据推送的,但是同样也有基于 UDP 的版本,叫做 MQTT-SN。
③、支持 QoS 服务质量等级。根据消息的重要性不同设置不同的服务质量等级。
④、小型传输,开销很小,协议交换最小化,以降低网络流量。这就是为什么在介绍里说它非常适合"在物联网领域,传感器与服务器的通信,信息的收集",要知道嵌入式设备的运算能力和带宽都相对薄弱,使用这种协议来传递消息再适合不过了,在手机移动应用方面,MQTT 是一种不错的 Android 消息推送方案。
⑤、使用 will 遗嘱机制来通知客户端异常断线。
⑥、基于主题发布/订阅消息,对负载内容屏蔽的消息传输。
⑦、支持心跳机制。
一、MQTT库安装
pip install paho-mqtt
二、代码
# coding=utf-8
import paho.mqtt.client as mqtt
import time,os,requests,json,threading
cafile = r"E:\Python\rootCA.PEM" #身份认证文件
certfile = r"E:\Python\ClientCA_11111.PEM"
keyfile = r"E:\Python\ClientKey_11111.PEM"
host = "xxxxxx" #主机地址
port = 8883 #端口号
data={"state":{"desired":{"WIFI_AP":"on"}}} #发布信息
sub_topic="@askey/dvr/xxxxxx/status" #订阅主题
pub_topic="@askey/dvr/xxxxxx/status" #发布主题
client = mqtt.Client() #创建一个mqtt对象
client.tls_set(cafile, certfile, keyfile) #加密身份认证
client.connect(host, port, 60) #连接mqtt服务器
client.loop_start() #后台运行一个线程来自动调用loop()
def on_connect(client, userdata, flags, rc):
if rc == 0:
print('连接成功') #0代表连接成功
client.subscribe(sub_topic) #订阅消息
else:
print('Connect Error status {0}'.format(rc)) #连接失败并显示错误代码
def on_message(client, userdata, msg):
print("主题:"+msg.topic + " 消息:" + str(msg.payload.decode('utf-8'))) #接收消息后处理函数
def mqtt_subscribe():
client.on_connect = client.subscribe(sub_topic) # 设置连接上服务器回调函数
client.on_message = on_message # 设置接收到服务器消息回调函数
#client.loop_forever() # 守护连接状态
def mqtt_publish():
while True:
client.publish(pub_topic, payload=str(data), qos=1) # 发布消息
time.sleep(2)
if __name__ == '__main__':
p = threading.Thread(target=mqtt_publish, name="Thread_pub" , args=()).start() #发布主题线程
s = threading.Thread(target=mqtt_subscribe, name="Thread_sub", args=()).start() #订阅主题线程