当前位置: 首页 > 后端技术 > Python

PythonMQTT客户端对比

时间:2023-03-26 18:58:58 Python

随着人工智能和大数据的兴起,Python以其优雅的语言风格、丰富的库、平缓的入门曲线,搭上了时代的顺风车,成为最流行的计算机编程之一语言,开始渗透到物联网等各个领域。Python上有很多优秀的MQTT客户端库。有了它们,我们可以用极少量的代码开发一个MQTT客户端应用。本文收集了三个常见的PythonMQTT客户端库,从库的开发、使用复杂度等多个角度进行了简单的比较,以方便读者的选择。同时,文章还提供了一个简单的Python示例,您可以将示例代码复制到编辑器中直接运行(要求Python3.5+,并安装相应的依赖包)。paho-mqttpaho-mqtt可以说是PythonMQTT开源客户端库中的佼佼者。它由Eclipse基金会开发。除了Python库,还支持主流编程语言,如C++、Java、JavaScript、Golang等。目前Python版本已经实现了3.1和3.1.1MQTT协议,最新实现了MQTT5.0开发版。在基金会的支持下,以每年一个版本的速度更新,截至本文发布时最新版本为1.5.0(2019年8月发布)。在GitHub主页上,提供了从入门到每个功能的详细解读的快速实现,涵盖了从初学者到高级用户需要了解的每一个部分。即使遇到超出范围的问题,也可以在Google上搜索,得到近20万条相关条目。它是目前最流行的MQTT客户端。能得到如此多的关注,除了代码稳定,还有它的易用性。Paho的界面使用起来非常简洁优雅,只需要少量的代码就可以实现MQTT订阅和消息发布。安装pip3installpaho-mqtt或gitclonehttps://github.com/eclipse/paho.mqtt.pythoncdpaho.mqtt.pythonpython3setup.pyinstallsubscriberimportpaho.mqtt.clientasmqtt#连接回调函数defon_connect(client,userdata,flags,rc):print(f"Connectedwithresultcode{rc}")client.subscribe("$SYS/#")#接收消息的回调函数defon_message(client,userdata,msg):print(msg.topic+""+str(msg.payload))client=mqtt.Client()client.on_connect=on_connectclient.on_message=on_messageclient.connect("broker.emqx.io",1883,60)client.loop_forever()Issuer将paho.mqtt.client导入为mqttimporttimedefon_connect(client,userdata,flags,rc):print(f"Connectedwithresultcode{rc}")client=mqtt.Client()client.on_connect=on_connectclient.connect("broker.emqx.io",1883,60)foriinrange(3):client.publish('a/b',payload=i,qos=0,retain=False)print(f"send{i}toa/b")time.sleep(1)client.loop_forever()甚至,一行代码即可订阅和发布。importpaho.mqtt.subscribeassubscribe#当这个函数被调用时,程序会阻塞在这里,直到有消息发送到paho/test/simpleTopicmsg=subscribe.simple("paho/test/simple",hostname="broker.emqx.io")print(f"{msg.topic}{msg.payload}")importpaho.mqtt.publishaspublish#发送消息publish.single("a/b","payload",hostname="broker.emqx.io")#或者一次发送多条消息msgs=[{'topic':"a/b",'payload':"multiple1"},("a/b","multiple2",0,False)]publish.multiple(msgs,hostname="broker.emqx.io")HBMQTTHBMQTT基于Pythonasyncio开发,仅支持3.1.1的MQTT协议。由于使用asyncio库,开发者需要使用3.4以上的Python版本。CPU的速度比磁盘、网络等IO操作要快很多。在一个线程中,无论CPU执行多快,遇到IO操作,都要停下来等待读写完成,这无疑浪费了大量的时间。为了解决这个问题,Python加入了异步IO的特性。在Python3.4中,asyncio被正式纳入标准库,在Python3.5中,增加了async/await关键字。用户可以很容易地在函数前添加async关键字来使函数异步。HBMQTT建立在asyncio标准库之上。它允许用户显式设置异步断点。通过异步IO,MQTT客户端在接收或发送消息时挂载当前任务,继续处理下一个任务。不过,HBMQTT鲜为人知。在谷歌上搜索,关于HBMQTT的条目只有6000多条,StackOverflow上只有10个问题。这意味着如果你选择HBMQTT,你需要很强的解决问题的能力。有趣的是,HBMQTT本身也是一个MQTT服务器。可以通过hbmqtt命令一键打开。$hbmqtt[2020-08-2809:35:56,608]::INFO-退出状态新[2020-08-2809:35:56,608]::INFO-进入状态开始[2020-08-2809:35:56,609]::INFO-Listener'default'bindto0.0.0.0:1883(max_connections=-1)安装pip3installhbmqtt或gitclonehttps://github.com/beerfactory/hbmqttcdhbmqttpython3setup.pyinstall订户importloggingimportasynciofromhbmqtt.clientimportMQTTClient,ClientExceptionfromhbmqtt.mqtt.constantsimportQOS_1,QOS_2asyncdefuptime_coro():C=MQTTClient()awaitC.connect('mqtt://broker.emqx.io/')等待C.subscribe([('$SYS/broker/uptime',QOS_1),('$SYS/broker/load/#',QOS_2),])try:foriinrange(1,100):message=awaitC.deliver_message()packet=message.publish_packetprint(f"{i}:{packet.variable_header.topic_name}=>{packet.payload.data}")awaitC.unsubscribe(['$SYS/broker/uptime','$SYS/broker/load/#'])等待C.disconnect()除了ClientExceptionasce:logging.error("Clientexception:%s"%ce)if__name__=='__main__':formatter="[%(asctime)s]%(name)s{%(filename)s:%(lineno)d}%(levelname)s-%(message)s"logging.basicConfig(level=logging.DEBUG,format=formatter)asyncio.get_event_loop().run_until_complete(uptime_coro())发布者importloggingimportasyncioimporttimefromhbmqtt.clientimportMQTTClientfromhbmqtt.mqtt.constantsimportQOS_0,QOS_1,QOS_2asyncdeftest_coro():C=MQTTClient()awaitC.connect('mqtt://broker.emqx.io/')任务=[asyncio.ensure_future(C.publish('a/b',b'用QOS_0测试消息',qos=QOS_0)),asyncio.ensure_future(C.publish('a/b',b'用QOS_1测试消息',qos=QOS_1)),asyncio.ensure_future(C.publish('a/b',b'TESTMESSAGEWITHQOS_2',qos=QOS_2)),]awaitasyncio.wait(tasks)logging.info("消息发布")awaitC.disconnect()如果__name__=='__main__':formatter="[%(asctime)s]%(name)s{%(filename)s:%(lineno)d}%(levelname)s-%(message)s"logging.basicConfig(level=logging.DEBUG,format=formatter)asyncio.get_event_loop().run_until_complete(test_coro())更多使用细节请参考官方文档:https://hbmqtt.readthedocs.io...gmqttgmqtt是一个开源客户端个人开发者库。默认支持MQTT5.0协议。如果连接的MQTTbroker不支持5.0协议,会降级到3.1重新连接。与前两者相比,gmqtt还处于初级开发阶段,本文发表时的版本号为0.6.7。但它是较早支持MQTT5.0的Python库之一,因此在网络上享有很高的知名度。同样,它建立在asyncio库之上,因此需要Python3.4+。安装pip3installgmqtt或gitclonehttps://github.com/wialon/gmqttcdgmqttpython3setup.pyinstall订阅者importasyncioimportosimportsignalimporttimefromgmqttimportClientasMQTTClientSTOP=asyncio.Event()defon_connect(client,flags,rc,properties):print('Connected')defon_message(client,topic,payload,qos,properties):打印(f'RECVMSG:{topic}{payload}')defon_subscribe(client,mid,qos,properties):打印('SUBSCRIBED')defon_disconnect(客户端,数据包,exc=None):打印('断开连接')defask_exit(*args):STOP.set()asyncdefmain(broker_host):client=MQTTClient(“客户端-id")client.on_connect=on_connectclient.on_message=on_messageclient.on_subscribe=on_subscribeclient.on_disconnect=on_disconnect#连接MQTT代理awaitclient.connect(broker_host)#订阅主题client.subscribe('TEST/#')#发送测试数据client.publish("TEST/A",'AAA')client.publish("TEST/B",'BBB')等待STOP.wait()awaitclient.disconnect()if__name__=='__main__':loop=asyncio.get_event_loop()loop.add_signal_handler(signal.SIGINT,ask_exit)loop.add_signal_handler(signal.SIGTERM,ask_exit)host='broker.emqx.io'loop.run_until_complete(main(host))发布者importasyncioimportosimportsignalimporttimefromgmqttimportClientasMQTTClientSTOP=asyncio.Event()defon_connect(client,flags,rc,properties):print('Connected')client.subscribe('TEST/#',qos=0)defon_message(client,topic,payload,qos,properties):print(f'RECVMSG:{topic},{payload}')defon_disconnect(client,packet,exc=None):print('Disconnected')defask_exit(*args):STOP.set()asyncdefmain(broker_host):client=MQTTClient("client-id")client.on_connect=on_connect客户端.on_message=on_messageclient.on_disconnect=on_disconnect等待client.connect(broker_host)client.publish('TEST/TIME',str(time.time()),qos=1)awaitSTOP.wait()awaitclient.disconnect()if__name__=='__main__':loop=asyncio.get_event_loop()循环。add_signal_handler(signal.SIGINT,ask_exit)loop.add_signal_handler(signal.SIGTERM,ask_exit)host='broker.emqx.io'loop.run_until_complete(main(host))如何选择介绍了这三个PythonMQTT客户端库之后,我们来看看如何为自己选择合适的MQTT客户端库。这三个客户端各有优缺点:paho-mqtt文档最好,代码风格通俗易懂,基础支持强,但文档目前版本不支持MQTT5.0。HBMQTT使用asyncio库实现,可以优化网络I/O带来的延迟。但是代码风格不友好,也不支持MQTT5.0。gmqtt也是通过asyncio库实现的。与HBMQTT相比,代码风格友好。最重要的是,它支持MQTT5.0。但发展进程缓慢,未来前景不明。因此,在选择时,可以参考以下思路:如果你是正常开发,想在生产环境中使用,paho-mqtt无疑是最佳选择,其稳定性和代码可读性远超其他两个库。遇到问题时,优秀的文档和网上大量的词条也可以帮助你找到更多的解决方案。熟练使用asyncio库的读者可以试试HBMQTT和gmqtt。如果你想学习、参与开源项目或使用MQTT5.0,不妨尝试一下gmqtt,尝试分享一个它的代码。版权声明:本文为EMQ原创,转载请注明出处。