人工知能とビッグデータの発展に伴い、Pythonはその優雅な言語スタイル、豊富なライブラリ、そして使いやすさから、最も人気のあるプログラミング言語の一つとなりました。また、IoTなどの様々な分野にも浸透し始めています。
Pythonには多くの優れたMQTTクライアントライブラリが存在します。これらのクライアントを使用すると、非常に少ないコードでMQTTクライアントアプリケーションを開発できます。
この記事では、一般的なPython MQTTクライアントライブラリを3つ集め、ライブラリの開発や使用の複雑さなどの観点から簡単に比較し、読者が選択する際の参考になるようにします。同時に、この記事では簡単なPythonの例を提供し、例のコードをエディタにコピーして直接実行することができます(Python 3.5以上が必要で、対応する依存パッケージをインストールする必要があります)。
paho-mqtt
paho-mqttは、PythonのMQTTオープンソースクライアントライブラリの中で最も優れていると言えます。Eclipse Foundationのリーダーシップの下で開発され、Pythonライブラリの他にも、C++、Java、JavaScript、Golangなどの主要なプログラミング言語をサポートしています。現在のPythonバージョンでは、3.1および3.1.1のMQTTプロトコルを実装し、最新の開発バージョンではMQTT 5.0も実装しています。
資金のサポートを受けて、年に1回のペースで更新されています。この記事が公開された時点での最新バージョンは1.5.0(2019年8月リリース)でした。
GitHubのホームページでは、使い始めるためのクイック実装から各機能まで、詳細な説明が提供されており、初心者から上級者まで必要なことはすべて網羅されています。範囲外の問題が発生した場合でも、Googleで検索すれば、約20万件の関連エントリーが得られます。最も人気のあるMQTTクライアントです。
コードの安定性と使いやすさがその理由です。Pahoのインターフェースは非常にシンプルで使いやすく、MQTTのサブスクリプションとメッセージングを実装するために少量のコードだけで済みます。
インストール
pip3 install paho-mqtt
または
git clone https://github.com/eclipse/paho.mqtt.python
cd paho.mqtt.python
python3 setup.py install
サブスクライバー
import paho.mqtt.client as mqtt
# 接続のコールバック関数
def on_connect(client, userdata, flags, rc):
print(f"Connected with result code {rc}")
client.subscribe("$SYS/#")
# 受信メッセージのコールバック関数
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.emqx.io", 1883, 60)
client.loop_forever()
パブリッシャー
import paho.mqtt.client as mqtt
import time
def on_connect(client, userdata, flags, rc):
print(f"Connected with result code {rc}")
client = mqtt.Client()
client.on_connect = on_connect
client.connect("broker.emqx.io", 1883, 60)
for i in range(3):
client.publish('a/b', payload=i, qos=0, retain=False)
print(f"send {i} to a/b")
time.sleep(1)
client.loop_forever()
たった一行のコードでもサブスクリプションとパブリッシュを実装できます。
import paho.mqtt.subscribe as subscribe
# この関数が呼ばれると、トピックpaho/test/simpleにメッセージが送信されるまでプログラムはここでブロックされる
msg = subscribe.simple("paho/test/simple", hostname="broker.emqx.io")
print(f"{msg.topic} {msg.payload}")
import paho.mqtt.publish as publish
# メッセージを送信する
publish.single("a/b", "payload", hostname="broker.emqx.io")
# または一度に複数のメッセージを送信する
msgs = [{'topic':"a/b", 'payload':"multiple 1"}, ("a/b", "multiple 2", 0, False)]
publish.multiple(msgs, hostname="broker.emqx.io")
HBMQTT
HBMQTTはPython asyncioをベースに開発され、3.1.1 MQTTプロトコルのみをサポートしています。asyncioライブラリを使用しているため、Python 3.4以上が必要です。
CPUはディスク、ネットワーク、その他のIO操作よりもはるかに高速です。しかし、スレッド内では、どれだけCPUが高速に実行されていても、IO操作に遭遇すると、読み書きが完了するまで停止して待つ必要があり、多くの時間が無駄になります。
この問題を解決するために、Pythonには非同期IOの機能が追加されました。Python 3.4でasyncioが標準ライブラリに公式に追加され、Python 3.5ではキーワードasync/awaitが追加されました。ユーザーは関数の前にasyncキーワードを簡単に使用して、それらを非同期関数にすることができます。
HBMQTTはasyncio標準ライブラリの上に構築されています。ユーザーは非同期ブレークポイントを明示的に設定することができます。非同期IOを通じて、MQTTクライアントはメッセージの受信または送信時に現在のタスクを保留し、次のタスクを続けることができます。
ただし、HBMQTTの知名度はそれほど高くありません。GoogleでHBMQTTを検索すると、わずか6,000件以上のエントリーが得られ、Stack Overflowではたった10の質問があります。つまり、HBMQTTを使用する場合は、問題解決能力が強くなければなりません。
興味深いことに、HBMQTTはMQTTブローカーでもあります。hbmqttコマンドを通じてワンクリックで有効にすることができます。
$ hbmqtt
[2020-08-28 09:35:56,608] :: INFO - Exited state new
[2020-08-28 0935:56,608] :: INFO - Entered state starting
[2020-08-28 09:35:56,609] :: INFO - Listener 'default' bind to 0.0.0.0:1883 (max_connections=-1)
インストール
pip3 install hbmqtt
または
git clone https://github.com/beerfactory/hbmqtt
cd hbmqtt
python3 setup.py install
サブスクライバー
パブリッシャー
公式ドキュメントはこちらを参照してください:https://hbmqtt.readthedocs.io/en/latest/。
gmqtt
gmqttは個人開発者によってオープンソース化されたクライアントライブラリです。デフォルトでMQTT 5.0プロトコルをサポートしていますが、接続されたMQTTエージェントが5.0プロトコルをサポートしていない場合は、3.1にダウングレードされ、再接続されます。
最初の2つと比較して、gmqttはまだ開発の初期段階にあり、この記事が公開された時点でのバージョンは0.6.7です。しかし、MQTT 5.0を早期にサポートしたPythonライブラリの一つであるため、ウェブ上ではよく知られています。
これもasyncioライブラリをベースに構築されているため、Python 3.4以降が必要です。
インストール
pip3 install gmqtt
または
git clone https://github.com/wialon/gmqtt
cd gmqtt
python3 setup.py install
サブスクライバー
import asyncio
import os
import signal
import time
from gmqtt import Client as MQTTClient
STOP = asyncio.Event()
def on_connect(client, flags, rc, properties):
print('Connected')
def on_message(client, topic, payload, qos, properties):
print(f'RECV MSG: {topic} {payload}')
def on_subscribe(client, mid, qos, properties):
print('SUBSCRIBED')
def on_disconnect(client, packet, exc=None):
print('Disconnected')
def ask_exit(*args):
STOP.set()
async def main(broker_host):
client = MQTTClient("client-id")
client.on_connect = on_connect
client.on_message = on_message
client.on_subscribe = on_subscribe
client.on_disconnect = on_disconnect
# Connectting the MQTT broker
await client.connect(broker_host)
# Subscribe to topic
client.subscribe('TEST/#')
# Send the data of test
client.publish("TEST/A", 'AAA')
client.publish("TEST/B", 'BBB')
await STOP.wait()
await client.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))
パブリッシャー
import asyncio
import os
import signal
import time
from gmqtt import Client as MQTTClient
STOP = asyncio.Event()
def on_connect(client, flags, rc, properties):
print('Connected')
client.subscribe('TEST/#', qos=0)
def on_message(client, topic, payload, qos, properties):
print(f'RECV MSG: {topic}, {payload}')
def on_disconnect(client, packet, exc=None):
print('Disconnected')
def ask_exit(*args):
STOP.set()
async def main(broker_host):
client = MQTTClient("client-id")
client.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect
await client.connect(broker_host)
client.publish('TEST/TIME', str(time.time()), qos=1)
await STOP.wait()
await client.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))
Python MQTTクライアントはどう選択するか
これら3つのPython MQTTクライアントライブラリを紹介した後、要件に合うMQTTクライアントライブラリの選択方法を見てみましょう。3つのクライアントはそれぞれ長所と短所があります:
paho-mqttは最も良いドキュメントを持ち、理解しやすいコードスタイル、強力な財団のサポートを持っていますが、現在のバージョンのドキュメントはMQTT 5.0をサポートしていません。
HBMQTTの実装はasyncioライブラリを使用しており、ネットワークI/Oによって引き起こされる遅延を最適化することができます。しかし、コードスタイルはユーザーフレンドリーではなく、MQTT 5.0もサポートしていません。
gmqttもasyncioライブラリをベースに実装されています。HBMQTTと比較して、よりフレンドリーなコードスタイルを持っています。最も重要なことは、MQTT 5.0をサポートしていますが、開発プロセスが遅く、将来は不確実です。
したがって、以下の考え方を参考に選択してください:
- 通常の開発者で、本番環境で使用したい場合、paho-mqttは間違いなく最良の選択です。その安定性とコードの読みやすさは、他の2つのライブラリをはるかに上回っています。問題が発生した場合、優れたドキュメントとインターネット上の多数のエントリーがより多くの解決策を見つけるのに役立ちます。
- asyncioライブラリに精通している読者は、HBMQTTとgmqttを試してみることができます。
- MQTT 5.0を学びたい、またはオープンソースプロジェクトに参加したい場合、gmqttを試してみて、それに対するプルリクエストを送信してみてください。
以上が、PythonのMQTTクライアントライブラリを選択する際の一つの考え方です。あなたのニーズに合ったものを選択し、PythonでのMQTTの実装に役立ててください。