编写MQTT客户端程序——python

一、关于MQTT协议的介绍

MQTT协议是基于发布/订阅模式的物联网通信协议,具有简单易实现、支持 QoS、报文小等特点,在物联网上应用极其广泛。
广泛应用于IOT的原因
①轻量可靠
MQTT 报文紧凑,可在严重受限的硬件设备和低带宽、高延迟的网络上实现稳定传输。
②ecology 生态更完善
覆盖全语言平台的客户端和 SDK, AWS IoT Core、 Azure IoT Hub 等顶级云厂商物联网平台标准通信协议,物联网事实标准。
③pubsub 发布/订阅模式
基于发布/订阅模式,发布订阅模式的优点在于发布者与订阅者的解耦:订阅者与发布者不需要建立直接连接、也不需要同时在线。
④iot 为物联网而生
提供心跳机制、遗嘱消息、QoS 质量等级+离线消息、主题和安全管理等全面的物联网应用特性。

二、MQTT 发布订阅模式

发布订阅模式使发送消息的客户端(发布者)与接收消息的客户端(订阅者)分离,发布者与订阅者不需要建立直接联系。我们既可以让多个发布者向一个订阅者发布消息,也可以让多个订阅者同时接收一个发布者的消息,它的精华在于由一个被称为代理的中间角色负责所有消息路由和分发的工作。在MQTT通讯过程,发布者,订阅者,中间代理是三个极其重要的角色。
总结归纳该种模式的优点如下
①订阅者与发布者不需要建立直接连接,新的订阅者想要加入网络时不需要修改发布者的行为,又称之为空间解耦。
②订阅者和发布者不需要同时在线,即便不存在订阅者也不影响发布者发布消息,时间解耦。

三、使用 MQTT 报文实现发布订阅

1.连接
对于一个客户端来说,必须包含Client ID,Username/password,Keep Alive等信息。
①Client ID
连接服务端的每个客户端都有唯一的 ClientId ,用于服务端识别客户端。客户端和服务端都必须使用 ClientId 识别两者之间的 MQTT 会话相关的状态。
②Username/Password
MQTT 可以通过发送用户名和密码来进行相关的认证和授权。
③Keep Alive(保持连接)
一个以秒为单位的时间间隔,指的是客户端传输完成一个控制报文的时刻到发送下一个报文的时刻之间允许空闲的最大时间间隔。客户端负责保证控制报文发送的时间间隔不超过保持连接的值。如果没有任何其它的控制报文可以发送,客户端必须发送一个PINGREQ报文。如果 Keep Alive 的值非零,并且服务端在一点五倍的 Keep Alive 时间内没有收到客户端的控制报文,它必须断开客户端的网络连接,认为网络连接已断开。
④Clean Session
客户端和服务端可以保存会话状态,以支持跨网络连接的可靠消息传输,这个标志告诉服务器这次连接是不是一个全新的连接。

客户端的会话状态包括:
已经发送给服务端,但是还没有完成确认的 QoS 1 和 QoS 2 级别的消息
已从服务端接收,但是还没有完成确认的 QoS 2 级别的消息
服务端的会话状态包括:
已经发送给客户端,但是还没有完成确认的 QoS 1 和 QoS 2 级别的消息
即将传输给客户端的 QoS 1和 QoS 2 级别的消息
已从客户端接收,但是还没有完成确认的 QoS 2 级别的消息
可选,准备发送给客户端的 QoS 0 级别的消息

2.Subscribe 订阅主题
客户端向服务端发送 Subscribe 报文用于创建一个或多个订阅。每个订阅注册客户端关心的一个或多个主题。为了将应用消息转发给与那些订阅匹配的主题,服务端发送 Publish 报文给客户端。Subscribe 报文为每个订阅指定了最大的 QoS 等级,服务端根据这个发送应用消息给客户端。

Subscribe 报文的有效载荷必须包含至少一对主题过滤器 和 QoS 等级字段组合。

服务端在收到客户端订阅报文后,会发送 Suback 报文给客户端,用于确认它已收到并且正在处理Subscribe 报文。
在这里插入图片描述
3.Publish 发布消息
Publish 报文是指从客户端向服务端或者服务端向客户端传输一个应用消息,服务器收到 Publish 报文后根据主题过滤器将消息转发给其他客户端。
Publish报文包括Topic,Qos,主题内容。

Topic
主题名(Topic Name)用于识别消息应该被发布到哪一个会话,服务端发送给订阅客户端的 Publish 报文的主题名必须匹配该订阅的主题过滤器。
QoS
QoS 表示应用消息分发的服务质量等级保证

在这里插入图片描述

说明:
过程大致如上面所描述,更多相关内容,请自行查找相关资料进行了解或参考下面链接进行进一步了解
https://www.emqx.io/cn/blog/how-to-use-mqtt-packet-to-implement-publishing-and-subscribing-functions

四、使用Python进行客户端编写

1.下载第三库paho-mqtt
打开Pycharm,选择File->Settings
在这里插入图片描述
接着在搜索框上输入想要的安装的第三方库名称,出现之后,选中它进行安装
在这里插入图片描述
2.创建.py代码文件
①发布消息客户端

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="192.168.43.98", 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="192.168.43.98", port = 61613, keepalive=60)  # 订阅频道
time.sleep(1)
# client.subscribe("public")
client.subscribe([("public", 0), ("test", 2)])
client.loop_forever()

3.运行结果
在这里插入图片描述
客户端2作为发布者,每间隔5s发布一条主题名为public的消息,客户端1作为订阅者,订阅了主题名为public的消息.客户端2每发布一条消息,服务器就会将该消息发送给客户端1
4.实现自定义消息内容发布
发布者客户端代码

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="192.168.43.98", 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)

订阅者代码基本不用动,注意两个主题名要保存一致
运行结果
在这里插入图片描述
对应服务器上连接的相关信息
在这里插入图片描述
说明:
本客户端采用的Apollo搭建的MQTT服务器.对于没有搭建MQTT服务器的,可以才网上提供的MQTT服务,其链接如下
https://www.emqx.io/cn/mqtt/public-mqtt5-broker
程序只需要修改Broker为broker.emqx.io和TCP端口为1883

五、与其他协议进行对比

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

MQTT主要应用于各大物联网平台,REST主要应用于各种API

六、小结

通过对MQTT的发布订阅模式的认识,可以很清楚的看到通信的整个过程。客户端的实现,主要包含三个部分,第一部分是实现连接MQTT服务器,第二部分是实现消息的订阅,第三部分是消息的发布。通过运行这个程序,你会发现即使订阅主题的客户端没有运行,发布客户端仍旧会按照规定进行发布消息。由此,可以看出发布者和订阅者两者之间并不会对对方造成影响。这便是这种方式通信的优点所在。

七、参考资料

1.python 实现 MQTT通信(客户端与服务器端)
2.https://www.emqx.io/cn/mqtt/public-mqtt5-broker

猜你喜欢

转载自blog.csdn.net/qq_43279579/article/details/111990976