このセクションでは、デバイスが MQTT ブリッジを使用して Cloud IoT Core と通信する方法について説明します。HTTP と MQTT の一般的な情報については、プロトコルをご覧ください。
このセクションで説明する各メソッドの詳細については、API ドキュメントを参照してください。 MQTT 関連のサンプルもご覧ください。
MQTT ブリッジを経由してパブリッシュするには:
デバイスに MQTT クライアントをインストールします。
デバイスに MQTT サーバー証明書をダウンロードします。
Cloud IoT Core に対してデバイスの認証を行うように MQTT クライアントを構成します。
mqtt.googleapis.com
または長期サポート ドメインを経由して TLS handshake を開始します。
MQTT サーバー
Cloud IoT Core は、ポート mqtt.googleapis.com:8883
をリッスンするマネージド ブローカーを実行して、MQTT プロトコルをサポートします。ポート 8883 は、安全な MQTT 接続のために IANA によって予約されている標準 TCP ポートです。このポートへの接続には、Eclipse Paho などのオープンソース クライアントでサポートされている TLS トランスポートを使用する必要があります。
ポート 8883 がファイアウォールによってブロックされている場合は、ポート 443(mqtt.googleapis.com:443
)を使用することもできます。
Quality of Service(QoS)
MQTT 仕様では、次の 3 つの Quality of Service(QoS)レベルについて説明しています。
- QoS 0(最大で 1 回配信)
- QoS 1(最低でも 1 回配信)
- QoS 2(正確に 1 回のみ配信)
Cloud IoT Core は QoS 2 をサポートしていません。QoS 2 メッセージをパブリッシュすると接続が閉じられます。QoS 2 で事前定義されたトピックにサブスクライブすると、QoS レベルが QoS 1 にダウングレードされます。
Cloud IoT Core では、QoS 0 と 1 は次のように機能します。
- QoS 1 の
PUBLISH
メッセージは、Cloud Pub/Sub に正常に送信された後、PUBACK
メッセージによって確認応答されます。 - QoS 0 の
PUBLISH
メッセージはPUBACK
レスポンスを必要とせず、メッセージ配信パスにジッターがある場合(たとえば、Cloud Pub/Sub が一時的に利用できない場合)に破棄されます。 - Cloud IoT Core の MQTT ブリッジは、配信不能なメッセージを再試行するために少量のバッファを保持します。バッファがいっぱいになった場合、QoS が 1 のメッセージは破棄され、
PUBACK
メッセージはクライアントに送信されません。クライアントは、メッセージを再送信する必要があります。
デバイス構成の場合、QoS レベルは次のとおりです。
- QoS が 0 の場合、特定の構成バージョンがデバイスに一度だけパブリッシュされます。デバイスが構成を受信しない場合は、再度登録する必要があります。したがって、構成が頻繁に(数秒または数分で)更新され、更新のたびにデバイスが受信する必要がない場合、QoS 0 が便利です。
- QoS が 1 の場合、デバイスが PUBACK で承認するまで、最新の構成の更新が再試行されます。古い構成が確認される前に新しい構成が push された場合、古い構成は再配信されません。代わりに、新しいメールが配信(および再配信)されます。このレベルはデバイス構成で最も安全なモードであり、最終的にデバイスが最新の構成を取得することが保証されます。
MQTT サーバー証明書をダウンロードする
TLS トランスポートを使用するには、デバイスが Cloud IoT Core と通信していることを、なりすましではなく Cloud IoT Core と通信していることを確認する必要があります。次の証明書パッケージが検証をサポートしています。
mqtt.googleapis.com
用の完全な Google ルート CA 認証パッケージ(128 KB)。- このパッケージは、Cloud IoT Core を含む Google のプロダクトやサービスと通信するための信頼チェーンを確立します。
- 完全なルート CA 認証パッケージを持つデバイスは、MQTT サーバーと直接通信します。
- このパッケージは定期的に更新されます。
mqtt.2030.ltsapis.goog
用の Google の最小ルート CA セット(1 KB 未満)。最小ルート CA セットには、プライマリ証明書とバックアップ証明書が含まれています。- このセットは、マイクロコントローラなどのメモリの制約があるデバイスを対象とし、Cloud IoT Core とのみ通信する信頼チェーンを確立します。
- 最小ルート CA セットを持つデバイスは、長期サポート ドメインを介して Cloud IoT Core と通信します。
- このセットは 2030 年まで固定です(プライマリ証明書とバックアップ証明書は変更されません)。セキュリティを強化するため、Google Trust Services は予告なしにプライマリ証明書とバックアップ証明書をいつでも切り替えることができます。
Google ルート CA 証明書をデバイスにダウンロードしたら、デバイスを認証する MQTT クライアントを構成し、MQTT サーバーに接続して MQTT ブリッジを介して通信を行うことができます。
MQTT クライアントを構成する
MQTT クライアントは、MQTT ブリッジに接続することによってデバイスを認証します。デバイスを認証するように MQTT クライアントを構成するには:
- MQTT クライアント ID を完全なデバイス パスに設定します。
projects/PROJECT_ID/locations/REGION/registries/REGISTRY_ID/devices/DEVICE_ID
- MQTT クライアントを MQTT サーバー証明書に関連付けます。
- MQTT ホスト名を
mqtt.googleapis.com
または長期サポート ドメインに設定します(最小ルート CA セットを使用した場合)。 - ユーザー名を指定します。MQTT ブリッジはユーザー名フィールドを無視しますが、一部の MQTT クライアント ライブラリは、username フィールドを指定しない限りパスワード フィールドを送信しません。最良の結果を得るには、
unused
やignored
などの任意のユーザー名を指定します。 - パスワードを設定する。パスワード フィールドには JWT を含める必要があります。
次のサンプルは、デバイスを認証するように MQTT クライアントを構成する方法を示しています。
C++
クライアント ID の構成とデバイスの認証の手順は、以下のハイライト表示のとおりです。Java
Node.js
Python
このサンプルでは、Python 用の Google API クライアント ライブラリを使用します。長期 MQTT ドメインを使用する
長期サポート(LTS)ドメインでは、1 つの TLS 構成を長期間使用できます。一度 MQTT クライアントを設定してから、LTS ドメインを介してメッセージをパブリッシュするように MQTT クライアントを構成し、サポートされている時間枠の間、MQTT ブリッジを介して継続的に通信を行うことができます。
現在アクティブな LTS ドメインは mqtt.2030.ltsapis.goog
です。この LTS ドメインは 2030 年までサポートされます。
LTS ドメインを使用するには:
LTS ドメインを介してメッセージをパブリッシュするように MQTT クライアントを構成します。
- Cloud IoT Core に対してデバイスの認証を行うように MQTT クライアントを構成します。
- デバイスを構成する際に、最小ルート CA セットのプライマリ証明書とバックアップ証明書を MQTT クライアントに関連付けます。
mqtt.2030.ltsapis.goog
を介してポート 8883 または 443 で TLS handshake を開始します。少なくとも次の TLS 機能を使用してください。- TLS 1.2
- 証明書鍵とハッシュ アルゴリズムとして SHA-256 を使用する P-256
- P-256 と暗号スイートの非圧縮ポイントを使用した TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- Server Name Indication(SNI)
- DNS over TCP または DNS over DNS
LTS ドメインに送信されるメッセージを含む、MQTT トラフィックの保護の詳細については、デバイスのセキュリティに関する推奨事項をご覧ください。
テレメトリー イベントをパブリッシュする
デバイスが MQTT クライアントを使用して構成され、MQTT ブリッジに接続されると、次の形式で PUBLISH
メッセージを MQTT トピックに対して発行することで、テレメトリー イベントをパブリッシュできます。
/devices/DEVICE_ID/events
デバイス ID は、MQTT クライアント ID で指定されたデバイスの文字列 ID です。デバイス ID では大文字と小文字が区別されます。
この MQTT トピックにパブリッシュされたメッセージは、対応するレジストリのデフォルトのテレメトリー トピックに転送されます。デフォルトのテレメトリー トピックは、レジストリ リソースの eventNotificationConfigs[i].pubsubTopicName
フィールドで指定された Cloud Pub/Sub トピックです。デフォルトの Pub/Sub トピックが存在しない場合、公開されたテレメトリー データは失われます。他の Cloud Pub/Sub トピックにメッセージをパブリッシュするには、他の Cloud Pub/Sub トピックにテレメトリー イベントを公開するをご覧ください。
転送されたメッセージ データ フィールドには、デバイスによってパブリッシュされたメッセージのコピーが含まれ、Cloud Pub/Sub トピックの各メッセージに次のメッセージ属性が追加されます。
属性 | 説明 |
---|---|
deviceId |
デバイス レジストリに対するユーザー定義の文字列 ID(thing1 など)。デバイス ID はレジストリ内で一意である必要があります。 |
deviceNumId |
サーバーが生成したデバイスの数値 ID。デバイスを作成すると、Cloud IoT Core によってデバイスの数値 ID が自動的に生成されます。グローバルに一意であり、編集することはできません。 |
deviceRegistryLocation |
デバイス レジストリの Google Cloud Platform リージョン(例: us-central1 )。 |
deviceRegistryId |
デバイス レジストリに対するユーザー定義の文字列 ID(registry1 など)。 |
projectId |
レジストリとデバイスを所有する Cloud プロジェクトの文字列 ID。 |
subFolder |
このサブフォルダは、イベントのカテゴリや分類として使用できます。MQTT クライアントの場合、サブフォルダは DEVICE_ID/events の後にあるサブトピックで、直接コピーされます。たとえば、クライアントが MQTT トピック /devices/DEVICE_ID/events/alerts にパブリッシュする場合、サブフォルダは文字列 alerts です。 |
次のサンプルは、MQTT 接続を介して PUBLISH
メッセージを送信する方法を示しています。
C++
このサンプルでは、Python 用の Google API クライアント ライブラリを使用します。Java
Node.js
Python
このサンプルでは、Python 用の Google API クライアント ライブラリを使用します。追加の Cloud Pub/Sub トピックにテレメトリー イベントをパブリッシュする
デバイスは、追加の Cloud Pub/Sub トピックにデータをパブリッシュできます。デフォルトでは、/devices/DEVICE_ID/events
にパブリッシュされた MQTT メッセージは、対応するレジストリのデフォルトのテレメトリー トピックに転送されます。MQTT トピックにサブフォルダを指定することで、データを追加の Cloud Pub/Sub トピックに転送できます。このサブフォルダは、/devices/DEVICE_ID/events
の後のサブトピックです。
サブフォルダにパブリッシュされたメッセージは、同じ名前の Cloud Pub/Sub トピックに転送されます。対応するレジストリは、Cloud Pub/Sub トピックが構成されている必要があります。構成されていない場合、メッセージはデフォルトの Cloud Pub/Sub トピックに転送されます。
次の場合、メッセージは追加の Cloud Pub/Sub トピックではなく、デフォルトの Cloud Pub/Sub トピックに転送されます。
- MQTT トピックでサブフォルダが指定されていない
- サブフォルダが MQTT トピックで指定されているが、デバイス レジストリに一致する Pub/Sub トピックがない
たとえば、デバイスが MQTT トピック /devices/DEVICE_ID/events/alerts
にパブリッシュする場合、サブフォルダは文字列 alerts
です。eventNotificationConfigs[i].subfolderMatches
フィールドと eventNotificationConfigs[i].pubsubTopicName
フィールドの両方が alerts
に設定されている場合、メッセージは追加の Cloud Pub/Sub トピックに転送されます。設定されていない場合、メッセージはデフォルトの Cloud Pub/Sub トピックに転送されます。
デバイスの状態を設定する
接続されたデバイスは、次の MQTT トピックに PUBLISH
メッセージを発行してデバイスの状態を報告できます。
/devices/DEVICE_ID/state
状態メッセージを分類して取得するには、デバイスの状態に関するトピックを使用してレジストリを構成します。デバイス状態のトピックは、StateNotificationConfig.pubsubTopicName
フィールドで指定された Cloud Pub/Sub トピックです。レジストリがデバイス状態のトピックで構成されている場合、これらのメッセージは、一致する Cloud Pub/Sub トピックにベスト エフォート方式で転送されます。
状態メッセージの取得について詳しくは、デバイスの状態の取得をご覧ください。
MQTT トラフィックを制限する
Cloud IoT Core によって、過剰な負荷を発生させるプロジェクトが制限されます。デバイスが失敗したオペレーションを待機することなく再試行すると、同じ Google Cloud プロジェクト内のすべてのデバイスに影響する上限をトリガーできます。
再試行する場合は、導入されたジッターを伴う切り捨て型指数バックオフ アルゴリズムを実装することを強くおすすめします。
キープアライブ
クライアントから最初の MQTT CONNECT
メッセージを送信する場合は、オプションの「keep-alive」値を指定できます。この値は、PUBLISH
メッセージなどのメッセージを送信することをブローカーがクライアントに期待する時間間隔(秒単位で測定)です。その間隔の間に、クライアントからブローカーにメッセージが送信されない場合、ブローカーは自動的に接続を終了します。指定した keep-alive 値は 1.5 で乗算されるため、10 分の keep-alive は実際には 15 分間隔になります。
詳しくは、MQTT 仕様をご覧ください。
クライアントの設定
Cloud IoT Core には、独自のデフォルトの keep-alive 値はありません。keep-alive の間隔を指定する場合は、クライアントで設定する必要があります。
最適な結果を得るには、クライアントの keep-alive 間隔を 60 秒以上に設定してください。C、Python、Node.js、Java の Paho MQTT ライブラリなど、多くのオープンソースのクライアント ライブラリでは、60 秒がデフォルトで使用されます。
アイドル時間の上限
keep-alive 間隔とは別に、Cloud IoT Core には独自の 20 分間のアイドル時間上限があります。この上限に基づき、クライアントが 20 分間メッセージを送信しない場合、keep-alive 間隔がより長く設定されていても、クライアント接続は自動的に終了します。keep-alive 値が指定されていない場合でも、デフォルトのアイドル タイムアウトである 20 分は有効です。
トラブルシューティング
接続に問題がある場合は、トラブルシューティングをご覧ください。