0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Python MQTTクライアントの比較

Posted at

人工知能とビッグデータの発展に伴い、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の実装に役立ててください。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?