在 Python 中使用 MQTT的方法


Posted in Python onAugust 18, 2020

Python 是一种广泛使用的解释型、高级编程、通用型编程语言。Python 的设计哲学强调代码的可读性和简洁的语法(尤其是使用空格缩进划分代码块,而非使用大括号或者关键词)。Python 让开发者能够用更少的代码表达想法,不管是小型还是大型程序,该语言都试图让程序的结构清晰明了。

MQTT 是一种基于发布/订阅模式的 轻量级物联网消息传输协议 ,可以用极少的代码和带宽为联网设备提供实时可靠的消息服务,它广泛应用于物联网、移动互联网、智能硬件、车联网、电力能源等行业。

本文主要介绍如何在 Python 项目中使用 paho-mqtt 客户端库 ,实现客户端与 MQTT 服务器的连接、订阅、取消订阅、收发消息等功能。

项目初始化

本项目使用 Python 3.6 进行开发测试,读者可用如下命令确认 Python 的版本。

➜ ~ python3 --version  
Python 3.6.7

选择 MQTT 客户端库

paho-mqtt 是目前 Python 中使用较多的 MQTT 客户端库,它在 Python 2.7 或 3.x 上为客户端类提供了对 MQTT v3.1 和 v3.1.1 的支持。它还提供了一些帮助程序功能,使将消息发布到 MQTT 服务器变得非常简单。

Pip 安装 Paho MQTT 客户端

Pip 是 Python 包管理工具,该工具提供了对 Python 包的查找、下载、安装、卸载的功能。

pip3 install -i https://pypi.doubanio.com/simple paho-mqtt

Python MQTT 使用

连接 MQTT 服务器

本文将使用 EMQ X 提供的 免费公共 MQTT 服务器 ,该服务基于 EMQ X 的 MQTT 物联网云平台 创建。服务器接入信息如下:

  • Broker: broker.emqx.io
  • TCP Port: 1883
  • Websocket Port: 8083

导入 Paho MQTT客户端

from paho.mqtt import client as mqtt_client

设置 MQTT Broker 连接参数

设置 MQTT Broker 连接地址,端口以及 topic,同时我们调用 Python random.randint 函数随机生成 MQTT 客户端 id。

broker = 'broker.emqx.io'
port = 1883
topic = "/python/mqtt"
client_id = f'python-mqtt-{random.randint(0, 1000)}'

编写 MQTT 连接函数

编写连接回调函数 on_connect ,该函数将在客户端连接后被调用,在该函数中可以依据 rc 来判断客户端是否连接成功。通常同时我们将创建一个 MQTT 客户端,该客户端将连接到 broker.emqx.io 。

def connect_mqtt():
 def on_connect(client, userdata, flags, rc):
 if rc == 0:
  print("Connected to MQTT Broker!")
 else:
  print("Failed to connect, return code %d\n", rc)
 # Set Connecting Client ID
 client = mqtt_client.Client(client_id)
 client.on_connect = on_connect
 client.connect(broker, port)
 return client

发布消息

首先定义一个 while 循环语句,在循环中我们将设置每秒调用 MQTT 客户端 publish 函数向 /python/mqtt 主题发送消息。

def publish(client):
 msg_count = 0
 while True:
  time.sleep(1)
  msg = f"messages: {msg_count}"
  result = client.publish(topic, msg)
  # result: [0, 1]
  status = result[0]
  if status == 0:
  print(f"Send `{msg}` to topic `{topic}`")
  else:
  print(f"Failed to send message to topic {topic}")
  msg_count += 1

订阅消息

编写消息回调函数 on_message ,该函数将在客户端从 MQTT Broker 收到消息后被调用,在该函数中我们将打印出订阅的 topic 名称以及接收到的消息内容。

def subscribe(client: mqtt_client):
 def on_message(client, userdata, msg):
 print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")

 client.subscribe(topic)
 client.on_message = on_message

完整代码

消息发布代码

# python 3.6

import random
import time

from paho.mqtt import client as mqtt_client


broker = 'broker.emqx.io'
port = 1883
topic = "/python/mqtt"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 1000)}'


def connect_mqtt():
 def on_connect(client, userdata, flags, rc):
 if rc == 0:
  print("Connected to MQTT Broker!")
 else:
  print("Failed to connect, return code %d\n", rc)

 client = mqtt_client.Client(client_id)
 client.on_connect = on_connect
 client.connect(broker, port)
 return client


def publish(client):
 msg_count = 0
 while True:
 time.sleep(1)
 msg = f"messages: {msg_count}"
 result = client.publish(topic, msg)
 # result: [0, 1]
 status = result[0]
 if status == 0:
  print(f"Send `{msg}` to topic `{topic}`")
 else:
  print(f"Failed to send message to topic {topic}")
 msg_count += 1


def run():
 client = connect_mqtt()
 client.loop_start()
 publish(client)


if __name__ == '__main__':
 run()

消息订阅代码

# python 3.6

import random
import time

from paho.mqtt import client as mqtt_client


broker = 'broker.emqx.io'
port = 1883
topic = "/python/mqtt"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 1000)}'


def connect_mqtt():
 def on_connect(client, userdata, flags, rc):
 if rc == 0:
  print("Connected to MQTT Broker!")
 else:
  print("Failed to connect, return code %d\n", rc)

 client = mqtt_client.Client(client_id)
 client.on_connect = on_connect
 client.connect(broker, port)
 return client


def publish(client):
 msg_count = 0
 while True:
 time.sleep(1)
 msg = f"messages: {msg_count}"
 result = client.publish(topic, msg)
 # result: [0, 1]
 status = result[0]
 if status == 0:
  print(f"Send `{msg}` to topic `{topic}`")
 else:
  print(f"Failed to send message to topic {topic}")
 msg_count += 1


def run():
 client = connect_mqtt()
 client.loop_start()
 publish(client)


if __name__ == '__main__':
 run()
消息订阅代码
# python3.6

import random

from paho.mqtt import client as mqtt_client


broker = 'broker.emqx.io'
port = 1883
topic = "/python/mqtt"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 100)}'


def connect_mqtt() -> mqtt_client:
 def on_connect(client, userdata, flags, rc):
 if rc == 0:
  print("Connected to MQTT Broker!")
 else:
  print("Failed to connect, return code %d\n", rc)

 client = mqtt_client.Client(client_id)
 client.on_connect = on_connect
 client.connect(broker, port)
 return client


def subscribe(client: mqtt_client):
 def on_message(client, userdata, msg):
 print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")

 client.subscribe(topic)
 client.on_message = on_message


def run():
 client = connect_mqtt()
 subscribe(client)
 client.loop_forever()


if __name__ == '__main__':
 run()

测试

消息发布

运行 MQTT 消息发布代码,我们将看到客户端连接成功,并且成功将消息发布。

python3 pub.py

在 Python 中使用 MQTT的方法

消息订阅

运行 MQTT 消息订阅代码,我们将看到客户端连接成功,并且成功接收到发布的消息。

python3 sub.py

在 Python 中使用 MQTT的方法

总结

至此,我们完成了使用 paho-mqtt 客户端连接到 公共 MQTT 服务器 ,并实现了测试客户端与 MQTT 服务器的连接、消息发布和订阅。

与 C ++ 或 Java 之类的高级语言不同,Python 比较适合设备侧的业务逻辑实现,使用 Python 您可以减少代码上的逻辑复杂度,降低与设备的交互成本。我们相信在物联网领域 Python 将会有更广泛的应用。

接下来我们将会陆续发布更多关于物联网开发及 Python 的相关文章,敬请关注。

以上就是在 Python 中使用 MQTT的方法的详细内容,更多关于Python 中使用 MQTT的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python类的基础入门知识
Nov 24 Python
python中list循环语句用法实例
Nov 10 Python
python目录与文件名操作例子
Aug 28 Python
50行Python代码实现人脸检测功能
Jan 23 Python
python unittest实现api自动化测试
Apr 04 Python
Selenium定时刷新网页的实现代码
Oct 31 Python
在python中使用requests 模拟浏览器发送请求数据的方法
Dec 26 Python
详解pandas如何去掉、过滤数据集中的某些值或者某些行?
May 15 Python
PyTorch基本数据类型(一)
May 22 Python
python3 sorted 如何实现自定义排序标准
Mar 12 Python
python3发送request请求及查看返回结果实例
Apr 30 Python
python绘制趋势图的示例
Sep 17 Python
安装pyecharts1.8.0版本后导入pyecharts模块绘图时报错: “所有图表类型将在 v1.9.0 版本开始强制使用 ChartItem 进行数据项配置 ”的解决方法
Aug 18 #Python
Python 处理日期时间的Arrow库使用
Aug 18 #Python
python七种方法判断字符串是否包含子串
Aug 18 #Python
Python使用socket模块实现简单tcp通信
Aug 18 #Python
python 浮点数四舍五入需要注意的地方
Aug 18 #Python
Python filter过滤器原理及实例应用
Aug 18 #Python
Python lambda表达式原理及用法解析
Aug 18 #Python
You might like
Yii分页用法实例详解
2014/12/04 PHP
详解php设置session(过期、失效、有效期)
2015/11/12 PHP
CodeIgniter分页类pagination使用方法示例
2016/03/28 PHP
php发送http请求的常用方法分析
2016/11/08 PHP
PHP远程连接oracle数据库操作实现方法图文详解
2019/04/11 PHP
Aster vs Newbee BO3 第二场2.18
2021/03/10 DOTA
document.getElementById的简写方式(获取id对象的简略写法)
2010/09/10 Javascript
qTip2 精致的基于jQuery提示信息插件
2012/02/17 Javascript
JavaScript执行效率与性能提升方案
2012/12/21 Javascript
用innerhtml提高页面打开速度的方法
2013/08/02 Javascript
用js控制组织结构图可以任意拖拽到指定位置
2014/01/17 Javascript
DIV始终居中的js代码
2014/02/17 Javascript
jQuery中prependTo()方法用法实例
2015/01/08 Javascript
js替换字符串中所有指定的字符(实现代码)
2016/08/17 Javascript
JS实现去除数组中重复json的方法示例
2017/12/21 Javascript
vue代码分割的实现(codesplit)
2018/11/13 Javascript
基于vue如何发布一个npm包的方法步骤
2019/05/15 Javascript
小程序识别身份证,银行卡,营业执照,驾照的实现
2019/11/05 Javascript
vue+Element-ui前端实现分页效果
2020/11/15 Javascript
Vue包大小优化的实现(从1.72M到94K)
2021/02/18 Vue.js
[05:53]完美世界携手游戏风云打造 卡尔工作室观战系统篇
2013/04/22 DOTA
简单文件操作python 修改文件指定行的方法
2013/05/15 Python
Python 专题四 文件基础知识
2017/03/20 Python
python如何为创建大量实例节省内存
2018/03/20 Python
python3 遍历删除特定后缀名文件的方法
2018/04/23 Python
详解python使用turtle库来画一朵花
2019/03/21 Python
Python实现汇率转换操作
2020/05/03 Python
详解pytorch tensor和ndarray转换相关总结
2020/09/03 Python
css3学习系列之移动属性详解
2017/07/04 HTML / CSS
canvas基础之图形验证码的示例
2018/01/02 HTML / CSS
AJAX都有哪些有点和缺点
2012/11/03 面试题
一套英文Java笔试题面试题
2016/04/21 面试题
小学教师寄语大全
2014/04/03 职场文书
单位介绍信格式
2015/01/31 职场文书
2015年环卫工作总结
2015/04/28 职场文书
2015年大班保育员工作总结
2015/05/18 职场文书