Amazon Web Services ブログ

AWS IoT Core の MQTT retained messages の利用方法

この記事は Roy Kincaid によって投稿された Getting started with MQTT retained messages for AWS IoT Core を翻訳したものです。

AWS は先日、AWS IoT Core の MQTT retained messages (保持されたメッセージ) の一般提供を発表しました。この機能では、特定の MQTT トピックごとに1つのメッセージを保存することで、トピックの現在および将来のサブスクライバーに配信することができます。retained message を作成するには、パブリッシュ時に retain フラグを設定し、AWS IoT Core のブローカーに保存することを知らせるだけです。この時点でメッセージは現在の全てのサブスクライバーに通常通り配信され、将来そのトピックをサブスクライブする新しいデバイスにも配信されます。また、今回の発表には、retained messages を管理するための新しい API と更新された API も含まれています。retained messages は、AWS IoT Core が利用可能なすべてのリージョンで使用できます。

この記事では、この機能の概要を説明し、今後の IoT プロジェクトを設計する際に念頭に置くべきいくつかのユースケースを共有し、AWS IoT コンソールとプログラムの両方で利用を開始する方法について説明します。

概要

retained messages は、MQTT 3.1.1 仕様で定義されており、メッセージをパブリッシュする際に retain フラグを ‘True’ に設定することで作成されます。このフラグは、AWS IoT Device SDK や、ほとんどの MQTT 3.1.1 互換のクライアントでサポートされています。保持されたメッセージは、現在サブスクライブしているクライアントには通常のメッセージと同様に配信され、そのトピックをサブスクライブした新規クライアントにも自動的に配信されます。retained message は、1つのトピックにつき1つしか保存できないため、既存の retained message がある場合は、新たに送信された retained message はそれを置き換えます。AWS IoT Core は、retained message を、最後に更新またはアクセスされてから最大3年間保存します。空のペイロードを持つ新しい retained message をパブリッシュすることで、特定のトピックに現在保持されているメッセージを削除することができます。これらのメッセージを管理するには、AWS IoT コンソール内の新しい「保持されたメッセージ (Retained messages)」ページを使用します。このページは、「管理 (Manage)」タブの下にあり、現在のリージョンで現在保持されているメッセージをすべて表示したり、更新したりすることができます。また、新しい ListRetainedMessagesGetRetainedMessage、および更新された Publish API を使用することで、HTTP 経由で管理を行うこともできます。

retained messages の使用例

1. デバイスに設定情報を配布する

retained messages を使用する理由の1つは、1つまたは複数のデバイスの構成設定を保存することです。これは、新たにプロビジョニングされたデバイスが最初にオンラインになった後、ブートストラッププロセスを終了するときや、デバイスが IoT アプリケーションに接続し、その機能を通知する必要があるときのディスカバリーメッセージとして役立つ可能性があります。また、デバイスや他のクライアントは、必要に応じて保持されたメッセージを最新の設定に更新することができます。このアプローチを、各デバイスが独自の構成トピックを持つようなデバイス単位で使用する場合は、AWS IoT Core の Device Shadow を検討する価値があります。違いとしては、保持されたメッセージはサブスクライブ時に自動的に配信されるのに対し、Device Shadow ではアップデートをサブスクライブし、必要に応じて現在の状態を意図的に要求できることが挙げられます。両者の主な違いを理解するには、Using MQTT retained messages に比較表が掲載されているので、特定のユースケースに適したツールを選択するのに役立ちます。

retained messages を使用するもう一つの理由は、共有された設定を複数のデバイスにブロードキャストすることです。例えば、複数のデバイスに送信する設定がある場合、該当するデバイスに共有のトピックをサブスクライブさせれば、その特定のトピックの現在および将来のサブスクライバー全てが、最新バージョンの共有設定を持つことができます。デバイス固有の設定は、デバイスシャドウで管理するか、固有のトピックに保持し、共有またはグループの設定は、共有トピック内に保持することができます。

例えば、あるユーザーが、複数のデバイスがサブスクライブするトピックにメッセージをパブリッシュしたとします。2台のオンラインのデバイスがそのメッセージを受信します。retain フラグが ‘True’ に設定されているため、AWS IoT Core ブローカーは、そのトピックを将来サブスクライブするデバイスのためにメッセージを保存します。3台目のデバイスが現在オフラインの場合、ユーザーが送信したメッセージは保持されているので、オフラインのデバイスが接続してそのトピックをサブスクライブすると、自動的にメッセージを受け取ることになります。

retained messages を使用して、複数のデバイスへの共有設定のブロードキャストを示す図。

2. デバイスの最後の状態を把握する

ratained messages のもう一つの使い方は、1つ以上のデバイスの現在の状態を保存することです。例えば、デバイスが定期的に現在の状態を固有のトピックにパブリッシュし、その都度 retain フラグを ‘True’ に設定することで、最新の状態が常に AWS IoT Core ブローカーに保存されるようにします。クラウドサービスや顧客向けアプリケーションなどの別のクライアントがデバイスの状態を必要とする場合は、デバイスが更新をパブリッシュするのを待つのではなく、特定のトピックをサブスクライブするだけで自動的に受け取ることができます。最初のデバイス構成の例と同様に、デバイスごとに固有の retained message トピックを使用して状態を維持するこのパターンは、デバイスシャドウとの共通点があるため、特定のユースケースに最適なオプションを選択する際には、Using MQTT retained messages の比較表を参照してください。

デバイスの現在の接続状態を保持するためには、‘Will Retain’ フラグを使用して、デバイスが異常な切断を行った場合に、特定のトピックの retained message が更新され、現在および将来のサブスクライバーがそのデバイスの現在の接続状態を知ることができるようにします。これにより、あるデバイスが予期しない切断を行った場合、そのデバイスが再接続する前にそのトピックをサブスクライブしている他のデバイスは、そのデバイスが現在オフラインであることを自動的に通知されます。

AWS IoT コンソールで retained messages を使う

AWS IoT コンソールで retained message をテストするには、MQTT テストクライアントと、管理セクションにある新しい保持されたメッセージのページを組み合わせて使用します。retained messages には、この機能へのアクセスを制御できる AWS IoT Core ポリシーアクションが関連付けられていることに注意することが重要です。retained messages へのアクセスを承認する方法の例を見るには、AWS IoT ポリシーの例をチェックしてください。まず、MQTT テストクライアントを使用して、retained message をテストトピックにパブリッシュします。その後、保持されたメッセージのタブからそのメッセージを表示・更新する方法を確認します。最後に、MQTT テストクライアントに戻り、そのテストトピックをサブスクライブして、retained message の配信をブラウザから確認します。では、さっそく始めましょう。

ステップ1:MQTT テストクライアントでテストメッセージをパブリッシュする

  1. AWS マネジメントコンソールにログインし、上部にあるサービスを選択し、AWS IoT Core に移動します。
  2. 左側のナビゲーションでテストを選択し、MQTT テストクライアントを選択します。
  3. トピックに公開するタブを選択し、テストに使用するトピック名を入力します。この例では、スマートホーム製品を作っていて、特定の設定のオプトイン利用やプレミアムサブスクリプションサービスなどのデバイス設定に影響を与えるアカウント設定を保存する、顧客ごとのトピックを設定したいとします。
    1. トピックとして “users/settings/user01” と入力します。
    2. メッセージに、お客様の現在のアカウントタイプを示す {“account_type” : “standard”} と入力します。
  4. 追加設定セクションを展開し、このトピックに関するメッセージを保持チェックボックスを選択します。
  5. 発行を選択します。

AWS コンソール内の MQTT テストクライアントを使用して保持されたメッセージをパブリッシュする方法を示すスクリーンショット

ステップ2: 保持されたメッセージページで retained message を表示する

  1. ratained message をパブリッシュしたので、左側のナビゲーションで管理を選択し、保持されたメッセージを選択します。ここから、現在 retained messages を持っているトピックのリストが表示されます。

AWS IoT コンソールで保持されたメッセージページを示すスクリーンショット

  1. ステップ1でメッセージをパブリッシュしたトピックを選択します。ここから、現在そのトピックに保存されている retained message を確認できます。

AWS IoT コンソール内で保持されたメッセージの詳細を示すスクリーンショット

ステップ3:MQTT テストクライアントでのサブスクライブ

テストメッセージが正常に保持されたことを確認したので、実際に見てみましょう。

  1. 左側のナビゲーションで、テストセクションの MQTT テストクライアントを選択します。
  2. トピックをサブスクライブするタブを選択します。
  3. トピックのフィルターに “users/settings/user01” と入力します。
  4. サブスクライブを選択します。保持されているメッセージが画面に表示されるはずです。

メッセージが保持されたトピックにサブスクライブしている MQTT テストクライアントのスクリーンショット

retained messages をプロジェクトで利用する

retained message は MQTT 3.1.1 仕様の標準機能なので、AWS IoT Device SDK やほとんどの MQTT クライアントでは、デバイスやアプリケーションロジック内から retained message のパブリッシュがサポートされています。AWS IoT Core の retained messages が仕様と異なる点は、特定のトピックに保存された retained message を受信するためには、ワイルドカード (例:#,*) を使用せずにトピックフィルタに正確に一致させる必要があることです。

AWS IoT Device SDK による retained message のパブリッシュ

AWS IoT Device SDK v2 for Python を使って、retained message をパブリッシュする例を見てみましょう。ここでは、MQTT Pub/Sub サンプルから、メッセージのパブリッシュを行うスニペットを紹介します。

mqtt_connection.publish(
    topic=args.topic,
    payload=message_json,
    qos=mqtt.QoS.AT_LEAST_ONCE
)

この例ではデフォルトで QoS 1 が設定されていますが、retained messages に対しては QoS 0 もサポートされています。retain フラグの設定についてですが、API ドキュメントを見てみると、publish を使用する際には retain=bool というパラメータを追加設定するだけで良いようです。

つまり、AWS IoT Device SDK v2 for Python で retained message をパブリッシュするには、次のようにスニペットの最後にパラメータを追加します。

mqtt_connection.publish(
    topic=args.topic,
    payload=message_json,
    qos=mqtt.QoS.AT_LEAST_ONCE,
    retain=True
)

サブスクライバーとしては、同じフラグをチェックすることで、retained messages を標準のメッセージと区別することができます。

これをテストするには、“users/settings/user01” というトピックに、“hello from python” という内容の新しい retained message をパブリッシュします。この例は、以下のコマンドラインで実行できます。

python3 pubsub.py --endpoint YOUR-ENDPOINT \
    --port 8883 \
    --cert YOUR-CERT \
    --key YOUR-KEY \
    --root-ca ROOT-CA \
    --client-id YOUR-CLIENT-ID \
    --topic users/settings/user01 \
    --count 1 \
    --message 'hello from python!'

AWS IoT コンソールで、この新しいメッセージが保持されたメッセージのセクションに反映されていることを確認します。

今回の例では Python を見ましたが、他の AWS IoT Device SDK でも retain フラグをサポートしているものがありますので、チェックしてみてください。

まとめ

AWS IoT Core の MQTT retained message では、トピックにメッセージを保存して、現在および将来のサブスクライバーに自動配信することができます。retained message の作成と管理は、AWS IoT コンソール内から、または AWS IoT Device SDK や、新しい ListRetainedMessagesGetRetainedMessage、更新された Publish API を介して行うことができます。関連するスロットリングとサービス制限の情報については、AWS IoT Core のエンドポイントとクォータを確認してください。この機能は、AWS IoT Core が利用可能なすべてのリージョンで現在利用可能です。詳細については、Using MQTT retained messages のドキュメントをご覧ください。

翻訳はソリューションアーキテクトの三平が担当しました。