当前位置:   article > 正文

MQTT服务搭建及python使用示例_mqtt python

mqtt python

1、MQTT协议

1.1、MQTT介绍

        MQTT(Message Queuing Telemetry Transport)是一种轻量级的、基于发布/订阅模式的通信协议,通常用于物联网设备之间的通讯。它具有低带宽、低功耗和开放性等特点,适合在网络带宽有限或者网络连接不稳定的环境下使用。MQTT协议使用TCP/IP协议栈进行通讯,支持多种编程语言和平台,并且能够提供可靠的消息传递机制。

        在MQTT中,设备可以发布消息到特定的主题(topic),同时其他设备可以订阅这些主题以接收相应的消息。这种发布/订阅模式使得设备之间的通讯更加灵活和高效。MQTT还支持三种服务质量等级:至多一次(at most once)、至少一次(at least once)和恰好一次(exactly once),以满足不同场景下对消息传递可靠性的需求。

        优点:代码量少,开销低,带宽占用小,即时通讯协议。

1.2、MQTT概念

        订阅(Subscribtion):订阅包含主题筛选器( Topic Filter )和最大服务质量( QoS )。订阅会与一个会话( Session )关联。一个会话可以包含多个订阅。每一个会话中的每个订阅都有一个不同的主题筛选器。

        会话(Session):每个客户端与服务器建立连接后就是一个会话,客户端和服务器之间有状态交互。会话存在于一个网络之间,也可能在客户端和服务器之间跨越多个连续的网络连接。

        主题名(Topic Name):连接到一个应用程序消息的标签,该标签与服务器的订阅相匹配。服务器会将消息发送给订阅所匹配标签的每个客户端。需要注意的是, MQTT 中消息主题按照层级命名,使用 ‘/’ 进行分割。此外,主题中可以使用通配符进行多个主题或多层级的订阅,有两种常见的通配符:

        单层通配符 + :单层通配符只能匹配一层的主题,例如: China/Beijing/+ ,可以匹配的只有 Beijing 这个主 题下面一层的主题,例如 Xicheng, DongCheng, Xuanwu 等等。

        多层通配符 # :顾名思义,多层通配符就是可以匹配多个层级的主题,例如: China/# ,可以匹配到的主题可能有:China/Beijing/Dongcheng, China/Shanghai/PuDong ,等等。

        主题筛选器(Topic Filter):一个对主题名通配符筛选器,在订阅表达式中使用,表示订阅所匹配到的多个主题。

        消息订阅:消息订阅者所具体接收的内容。

1.3、MQTT中的角色

        Publisher 和 Subscriber 为客户端,Broker 为服务器端,消息主题为消息类型,Broker 根据 Topic 过滤消息,并将消息向客户端推送。

MQTT 中用 QoS 表示服务质量, MQTT 协议中有三种服务质量 (QoS) :

        1 ) QoS =0 ,至多一次,可能会出现丢包的情况,使用在对实时性要求不高的情况,例如,将此服务质量与通信环境传感器数据一起使用。 对于是否丢失个别读取或是否稍后立即发布新的读取并不重要。

        2 ) QoS =1, 至少一次,保证包会到达目的地,但是可能出现重包。

        3 ) QoS =2, 刚好一次,保证包会到达目的地,且不会出现重包的现象。

客户端:

        Publisher 和 Subscriber 都属于客户端。

        发布应用消息给其它相关的客户端。

        订阅以请求接受相关的应用消息。

        取消订阅以移除接受应用消息的请求。

        从服务端断开连接

服务器:

        服务器端即所谓的 MQTT Broker 服务器。

        接受来自客户端的网络连接。

        接受客户端发布的应用消息。

        处理客户端的订阅和取消订阅请求。

        转发应用消息给符合条件的已订阅客户端。

MQTT 提供的公共服务器端( Broker )有:

  1. test.mosquitto.org
  2. broker.hivemq.com
  3. iot.eclipse.org

2、基于公共服务示例

        在次,选择使用EMQX提供的免费MQTT公共服务器,但同样可以选择其他任何MQTT broker。The Free Global Public MQTT Broker | Try Now | EMQ (emqx.com)

  1. Broker: broker.emqx.io
  2. TCP Port: 1883
  3. Websocket Port: 8083

python库:pip install paho-mqtt=="1.6.1"

消息发布代码,pub.py

  1. import time
  2. import random
  3. from paho.mqtt import client as mqtt_client
  4. broker = 'broker.emqx.io'
  5. port = 1883
  6. topic = "/flask/mqtt"
  7. # generate client ID with pub prefix randomly
  8. client_id = f'python-mqtt-{random.randint(0, 1000)}'
  9. def connect_mqtt():
  10. def on_connect(client, userdata, flags, rc):
  11. if rc == 0:
  12. print("Connected to MQTT Broker!")
  13. else:
  14. print("Failed to connect, return code %d\n", rc)
  15. client = mqtt_client.Client(client_id)
  16. client.on_connect = on_connect
  17. client.connect(broker, port)
  18. return client
  19. def publish(client):
  20. msg_count = 0
  21. while True:
  22. time.sleep(1)
  23. msg = f"messages: {msg_count}"
  24. result = client.publish(topic, msg)
  25. # result: [0, 1]
  26. status = result[0]
  27. if status == 0:
  28. print(f"Send `{msg}` to topic `{topic}`")
  29. else:
  30. print(f"Failed to send message to topic {topic}")
  31. msg_count += 1
  32. def run():
  33. client = connect_mqtt()
  34. client.loop_start()
  35. publish(client)
  36. if __name__ == '__main__':
  37. run()

运行打印结果:

消息订阅代码,sub.py:

  1. import random
  2. from paho.mqtt import client as mqtt_client
  3. broker = 'broker.emqx.io'
  4. port = 1883
  5. topic = "/flask/mqtt"
  6. # generate client ID with pub prefix randomly
  7. client_id = f'python-mqtt-{random.randint(0, 100)}'
  8. def connect_mqtt() -> mqtt_client:
  9. def on_connect(client, userdata, flags, rc):
  10. if rc == 0:
  11. print("Connected to MQTT Broker!")
  12. else:
  13. print("Failed to connect, return code %d\n", rc)
  14. client = mqtt_client.Client(client_id)
  15. client.on_connect = on_connect
  16. client.connect(broker, port)
  17. return client
  18. def subscribe(client: mqtt_client):
  19. def on_message(client, userdata, msg):
  20. print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
  21. client.subscribe(topic)
  22. client.on_message = on_message
  23. def run():
  24. client = connect_mqtt()
  25. subscribe(client)
  26. client.loop_forever()
  27. if __name__ == '__main__':
  28. run()

运行打印结果:

        可以看到,发布和订阅成功。注意:每个客户端的ID唯一,不能重复!

3、基于Apollo服务示例

3.1、安装Apollo服务

        服务器端搭建:

Index of /dist/activemq/activemq-apollo/1.7.1

解压并打开目标如下:

        Apollo中间件其实是免安装的,我们只需要下载apache-apollo-1.7.1-windows-distro.zip,然后解压到某个文件夹就可以了。在这里我解压到D:\dist\apache-apollo-1.7.1。在apache-apollo-1.7.1/bin目录下打开终端执行命令:apollo create myapollo

        若出现如下错误 Loading configuration file ‘D:\phpStudy\apache-apollo-1.7.1\bin\mybroker\etc\apollo.xml’.Startup failed: java.lang.NoClassDefFoundError: javax/xml/bind/ValidationEventHandler,处理方式:换上jdk1.8版本即可。

        然后在生成的myapollo目录的bin目录下执行:pollo-broker.cmd run,结果如下:

        服务搭建成功,进入后台管理,打开网页,输入ip + : 61680 进入后台管理 ,默认用户名admin 密码 password,例如:http://127.0.0.1:61680

3.2、示例代码

本地服务基础信息:

  1. host="127.0.0.1"
  2. port = 61613
  3. 用户名:admin
  4. 密码:password

python库:pip install paho-mqtt=="1.6.1"

发布主题,publish.py

  1. import sys
  2. import time
  3. import paho.mqtt.client as mqtt
  4. def on_connect(client, userdata, flags, rc):
  5. print("Connected with result code " + str(rc))
  6. def on_subscribe(client, userdata, mid, granted_qos):
  7. print("消息发送成功")
  8. client = mqtt.Client(protocol=3)
  9. client.username_pw_set("admin", "password")
  10. client.on_connect = on_connect
  11. client.on_subscribe = on_subscribe
  12. client.connect(host="127.0.0.1", port=61613, keepalive=60) # 订阅频道
  13. time.sleep(1)
  14. i = 0
  15. while True:
  16. try:
  17. # 发布MQTT信息
  18. sensor_data = "test" + str(i)
  19. client.publish(topic="public", payload=sensor_data, qos=0)
  20. time.sleep(5)
  21. i += 1
  22. except KeyboardInterrupt:
  23. print("EXIT")
  24. client.disconnect()
  25. sys.exit(0)

订阅主题,subscribe.py

  1. import time
  2. import paho.mqtt.client as mqtt
  3. # The callback for when the client receives a CONNACK response from the server.
  4. def on_connect(client, userdata, flags, rc):
  5. if rc == 0:
  6. print("连接成功")
  7. print("Connected with result code " + str(rc))
  8. def on_message(client, userdata, msg):
  9. print(msg.topic + " " + str(msg.payload))
  10. client = mqtt.Client(protocol=3)
  11. client.username_pw_set("admin", "password")
  12. client.on_connect = on_connect
  13. client.on_message = on_message
  14. client.connect(host="127.0.0.1", port=61613, keepalive=60) # 订阅频道
  15. time.sleep(1)
  16. # client.subscribe("public")
  17. client.subscribe([("public", 0), ("test", 2)]) # 订阅
  18. client.loop_forever()

执行脚本后,正确大小消息。浏览器可见连接记录。

4、EMQX客户端工具

下载地址:MQTTX 下载选择适合您的平台,立即开始使用 MQTTX。icon-default.png?t=N7T8https://mqttx.app/zh/downloads

4.1、公共服务测试消息接收

创建连接:

  1. Host:为代码中定义好的 broker.emqx.io
  2. Port:为代码中定义好的 1883
  3. 用户名、密码根据需要添加

添加订阅:

主题为:/flask/mqtt

在MQTTX中发布消息:

测试成功。

4.2、自建服务测试消息接收

MQTT版本选择3.1.1,以下参数,与服务保持一致:

  1. host="127.0.0.1"
  2. port = 61613
  3. 用户名:admin
  4. 密码:password

其它测试步骤,一样。(创建主题,测试)

5、EMQX代理服务器

        windows下搭建MQTT代理服务,与Apollo服务功能一样,更方便好用,下载地址:https://www.emqx.io/zh/downloads

        下载后解压,进入目录bin文件下,执行:emqx start 

        打开浏览器输入 http://localhost:18083 进入EMQ的web控制台,输入用户名:admin 密码:public 进行登录。登录进入后,界面如下:

至此,代理服务器已经创建完成!客户端就可以连接代理服务器进行消息的分发和订阅!

附录:

java1.8.1下载,地址:Java Downloads | Oracleicon-default.png?t=N7T8https://www.oracle.com/java/technologies/downloads/#java8-windows

参考:

1、嵌入式QT- QT使用MQTT

嵌入式QT- QT使用MQTT_qt mqtt-CSDN博客

2、Python实现通信协议(mqtt)5星,mqtt flask

【小沐学Python】Python实现通信协议(mqtt)_python mqtt-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/718248
推荐阅读
相关标签
  

闽ICP备14008679号