基于Python的MQTT客户端程序

基于Python的MQTT客户端程序



任务摘要

利用网上提供的MQTT服务,编写MQTT客户端程序(python),自定义一个天气预报主题,完成订阅与发布。思考MQTT与前面REST协议的区别。
有关MQTT协议的详细解说,可参考下面博客:
熟悉HTTP&MQTT协议-实践练习.


一、MQTT简介

1.协议简介

MQTT 全称为 Message Queuing Telemetry Transport(消息队列遥测传输)是一种基于发布/订阅范式的“轻量级”消息协议,由 IBM 发布。
MQTT是一种发布/订阅传输协议,基本原理和实现如下
在这里插入图片描述

2.基本概念

MQTT 客户端

一个使用 MQTT 协议的设备、应用程序等,它总是建立到服务器的网络连接。

  1. 可以发布信息,其他客户端可以订阅该信息
  2. 订阅其它客户端发布的消息
  3. 退订或删除应用程序的消息
  4. 断开与服务器连接
    MQTT 服务器

MQTT 服务器也称为 Broker(消息代理),以是一个应用程序或一台设备。它是位于消息发布者 和订阅者之间

  1. 接受来自客户端的网络连接
  2. 接受客户端发布的应用信息
  3. 处理来自客户端的订阅和退订请求
  4. 向订阅的客户转发应用程序消息

3.MQTT控制报文

MQTT协议工作在TCP之上,端和代理之间通过交换预先定义的控制报文来完成通信。MQTT报文有3个部分组成,并按下表顺序出现:
在这里插入图片描述
所有的MQTT控制报文都有一个固定报头,期格式如下:
在这里插入图片描述
0和15为系统保留值;0-3位为标志位,依照报文类型有不同的含义,事实上,除了 PUBLISH 报文以外,其他报文的标志位均为系统保留。如果收到报文的标志位无效,代理应断开连接。
在这里插入图片描述

4.MQTT 5.0 协议新增介绍

MQTT 5.0 协议相比 MQTT 3.1.1 协议新增了许多内容, 比如说属性,AUTH 包,还有对一些字段做了修改,比如将 Clean Session 修改成 Clean Start 配合 Session Expiry Internal 去实现更灵活的会话控制。

设计目标
1.增强了扩展性
2.改善了错误报告的方式
3.定型了一些通用范式,例如能力发现和请求、响应扩展机制包括用户属性(user properties)
4.性能改善,并且添加了对小客户端(small clients) 的支持
属性
为了达成新协议的设计目标,MQTT 5.0 协议中新增了许多属性,以下是新添加的属性列表。
在这里插入图片描述
此为部分新增属性列表,更加详细的内容可参考资料链接。(MQTT 协议基本介绍

二、Python编写客户端

下载第三库paho-mqtt
打开Pycharm,选择File->Settings
在这里插入图片描述
搜索库名称,并进行安装
在这里插入图片描述
编写程序
发布消息客户端

import time
import sys
def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))
def on_subscribe(client,userdata,mid,granted_qos):
    print("消息发送成功")
client = mqtt.Client(protocol=3)
client.username_pw_set("admin", "password")
client.on_connect = on_connect
client.on_subscribe = on_subscribe
client.connect(host="10.60.225.123", port = 61613, keepalive=60)  # 订阅频道
time.sleep(1)
i = 0
#循环发布消息
while True:
    try:
        # 发布MQTT信息
        sensor_data = "test" + str(i)
        client.publish(topic="public", payload=sensor_data, qos=0)
        time.sleep(5)
        i += 1
    except KeyboardInterrupt:
        print("EXIT")
        client.disconnect()
        sys.exit(0)

订阅消息客户端

import time

import paho.mqtt.client as mqtt
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    if rc == 0:
        print("连接成功")
        print("Connected with result code " + str(rc))

def on_message(client, userdata, msg):
    print(msg.topic + " " + str(msg.payload))
client = mqtt.Client(protocol=3)
client.username_pw_set("admin", "password")
client.on_connect = on_connect
client.on_message = on_message
client.connect(host="10.60.225.123", port = 61613, keepalive=60)  # 订阅频道
time.sleep(1)
# client.subscribe("public")
client.subscribe([("public", 0), ("test", 2)])
client.loop_forever()

运行结果
在这里插入图片描述
实现自定义消息内容发布
客户端代码

import sys
def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))
def on_subscribe(client,userdata,mid,granted_qos):
    print("消息发送成功")
client = mqtt.Client(protocol=3)
client.username_pw_set("admin", "password")
client.on_connect = on_connect
client.on_subscribe = on_subscribe
client.connect(host="10.60.225.123", port = 61613, keepalive=60)  # 订阅频道
time.sleep(1)
i = 0
while True:
    sensor_data=input("请输入要发表消息内容(0表示退出):")
    if(sensor_data=='0'):
        break
    try:
        # 发布MQTT信息
        client.publish(topic="weather", payload=sensor_data, qos=0)
        time.sleep(5)
        # i += 1
    except KeyboardInterrupt:
        print("EXIT")
        client.disconnect()
        sys.exit(0)

服务器端代码

import time

import paho.mqtt.client as mqtt
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    if rc == 0:
        print("连接成功")
        print("Connected with result code " + str(rc))

def on_message(client, userdata, msg):
    print(msg.topic + " " + str(msg.payload))
client = mqtt.Client(protocol=3)
client.username_pw_set("admin", "password")
client.on_connect = on_connect
client.on_message = on_message
client.connect(host="10.60.225.123", port = 61613, keepalive=60)  # 订阅频道
time.sleep(1)
# client.subscribe("public")
client.subscribe([("public", 0), ("test", 2)])
client.loop_forever()

运行结果
在这里插入图片描述

三、与REST协议对比

MQTT:
①TCP协议,长连接
②适合做设备反向控制
③实时性控制
REST:
①TCP协议,短连接
②不适合做设备实时反向控制
③实时性控制不是很好


四、总结

对MQTT的协议有更加深入的了解,通过对MQTT客户端程序的编写,可以清除看到MQTT协议在消息的发布与订阅过程。发布与订阅互不影响。

五、参考资料

MQTT 协议基本介绍.
REST.

猜你喜欢

转载自blog.csdn.net/QWERTYzxw/article/details/112204248