MQTT プロトコルの概要

ここでは、MQTT プロトコルの簡単な概要と Kii Cloud での用途を説明します。

プロトコルの詳細な仕様については、IBM 社の資料 をご覧ください。日本語版の資料は WebSphere の技術文書 としても公開されています。

構成

MQTT は、発行/購読型のメッセージ処理を実現するための軽量なプロトコルとして設計されています。

メッセージのサブスクライバー(購読者)は、メッセージのパブリッシャー(発行元)が提供する MQTT トピックをあらかじめ講読しておきます。MQTT トピックに何か変化があると、サブスクライバーは PUBLISH コマンドを受け取ってそれを知ることができます。

MQTT トピックの講読やメッセージの送信の仲介役となるのがブローカーです。

Kii Cloud では、図のブローカー以下の要素はクラウド側の機能として提供されています。クライアントから見ると、ブローカーのホスト名とポート番号が分かれば MQTT 接続を実現できます。

コマンド

MQTT はコネクション指向のプロトコルです。クライアントとサーバーの間でコネクションを確立した後は、そのコネクション上でコマンドを双方向に送信し合います。

クライアントとサーバーは、以下の表に示されているコマンドを送信することで、目的の機能を実現します。表の情報のうち、Kii Cloud での利用方法や通信方向は、Kii Cloud での標準的な利用シーンに合わせたものです。

コマンド 説明 Kii Cloud での利用方法 通信方向
CONNECT クライアントがサーバーへの接続を要求 接続開始時 :thing::protocol_right::kii:
CONNACK 接続確認応答 接続開始時(応答) :thing::protocol_left::kii:
PUBLISH メッセージのパブリッシュ API のリクエスト :thing::protocol_right::kii:
API のレスポンス、プッシュ通知 :thing::protocol_left::kii:
PUBACK パブリッシュ確認応答 QoS 0 のみサポートのため未使用
PUBREC パブリッシュの受信(送達保証 パート 1) QoS 0 のみサポートのため未使用
PUBREL パブリッシュ のリリース(送達保証 パート 2) QoS 0 のみサポートのため未使用
PUBCOMP パブリッシュの完了(送達保証パート 3) QoS 0 のみサポートのため未使用
SUBSCRIBE クライアント・サブスクライブ要求 プッシュ通知の初期化 :thing::protocol_right::kii:
SUBACK サブスクライブ確認応答 プッシュ通知の初期化(応答) :thing::protocol_left::kii:
UNSUBSCRIBE クライアント・アンサブスクライブ要求 プッシュ通知の終了 :thing::protocol_right::kii:
UNSUBACK アンサブスクライブ確認応答 プッシュ通知の終了(応答) :thing::protocol_left::kii:
PINGREQ PING 要求 PING 要求 :thing::protocol_right::kii:
PINGRESP PING 応答 PING 応答 :thing::protocol_left::kii:
DISCONNECT クライアント切断中 クライアント切断中 :thing::protocol_right::kii:

※「説明」列は IBM 社の資料 より引用しています。

※ 「通信方向」列の :thing::protocol_right::kii: は Kii Cloud へのコマンド送信、:thing::protocol_left::kii:は MQTT クライアントへのコマンド送信を表します。

これらのコマンドは、MQTT プロトコルが定めるフォーマットに従ってコネクション上でやりとりします。通常、Web アプリや Thing などのクライアントでは、コマンドの送受信を MQTT ライブラリー経由で行うため、通信フォーマットを直接意識する必要がありません。クライアントでは、コマンドの送受信のタイミングと、コマンドのペイロードの情報を中心に制御します。

Kii Cloud での各コマンドの使用方法は、MQTT 経由でのプッシュ通知の利用、および、MQTT 経由での API の利用 をご覧ください。

MQTT トピック

MQTT プロトコルでは、メッセージの講読や発行の対象として MQTT トピックを使用します。

プロトコル上、MQTT トピックはパブリッシャーに複数存在し、それらは階層を持ったトピック名として表現されます。サブスクライバーは MQTT のトピック名を指定してそのトピックを講読したり、メッセージを発行したりできます。

Kii Cloud では、次の 2 通りの用途で MQTT トピックを使用します。

  • MQTT 経由でのプッシュ通知の利用

    プッシュ通知では、MQTT のコネクション 1 つに対して 1 個の MQTT トピックを使用します。

    MQTT トピックを SUBSCRIBE コマンドによって講読することで、プッシュ通知を実現します。サーバー側でイベントが発生すると、その MQTT トピックから PUBLISH コマンドが発行されて、クライアントにプッシュメッセージが届きます。

    プッシュ通知を使用する場合は SUBSCRIBE コマンドによる講読操作を行います。

  • MQTT 経由での API の利用

    API の実行では、実行したい API の URL 階層に対応する形で、複数個の MQTT トピックを使用します。

    MQTT トピックの階層構造を利用して、実行したい API の機能を識別します。目的の機能を提供する MQTT トピックに PUBLISH コマンドを送ると、Kii Cloud へのリクエストを行ったものとして処理します。レスポンスはサーバー側からの PUBLISH コマンドとして受け取ります。

    API の実行を行う場合、講読操作は行わず、PUBLISH コマンドの送信と受信のみを行います。

Quality of Service

Kii Cloud が提供する MQTT の Quality of Service は、QoS 0 です。1 回のイベントの発生に対して最大 1 回のプッシュ通知を受け取れますが、通知を受け取れなかった場合の再試行は行われません。

MQTT クライアントは、QoS 1 以上の機能の実現に必要な PUBACK、PUBREC、PUBREL、PUBCOMP コマンドの処理を行う必要がありません。

キープアライブタイマー

MQTT プロトコル では、クライアントからのネットワーク接続が切断されたことを検出するため、キープアライブタイマーを使用します。クライアントから一定時間メッセージの送信がない場合、接続が失われたものとしてサーバー側から接続を切断します。

キープアライブタイマーの設定値は、接続時に CONNECT コマンドのパラメーターとして指定します。以下のシーケンスのように、一定時間、クライアントからのメッセージの送信がない場合、PINGREQ コマンドを送信して接続が切られないようにします。

PINGREQ コマンドの処理方法はライブラリーによって異なります。MQTT ライブラリーの内部で自動的に送信される場合と、ユーザープログラムから送信指示を出して送信する場合の 2 通りがあります。送信指示が必要かどうかについては、利用する MQTT ライブラリーの仕様をご確認ください。

Web アプリまたは Thing の開発時には、MQTT クライアントを実装してから送信コマンドがない状態でしばらく放置し、コネクションが切れないことを確認しておくことをお勧めします。コネクションが一定時間で切れる場合、キープアライブタイマーの問題である可能性があります。

MQTT が使用するコネクション

MQTT プロトコルを使って通信を行うには、クライアントとサーバーの間でコネクションが必要です。MQTT プロトコルで定められているコマンドは、コネクションの上でやりとりされます。

Kii Cloud を利用する際、クライアントは以下の表に示す 4 通りの接続方法から 1 つを選択します。

接続方法 SSL/TSL あり SSL/TSL なし
TCP ソケット上の MQTT Thing などで利用 セキュリティが低下するため非推奨
WebSocket 上の MQTT Web ブラウザーなどで利用 セキュリティが低下するため非推奨

Kii Cloud の初期登録やプッシュ通知の API では、これら 4 通りのポート番号が返されます。クライアントの実装に合わせて、利用するポート番号を選択します。

基本的にどのコネクションでも利用できますが、クライアントによって適している方式があります。

  • Thing から利用する場合は、シンプルな TCP ソケット上で MQTT を使用する方法が適しています。

  • Web アプリで使用する場合は、HTTP と相性がよい WebSocket 上の MQTT を使用するのが適しています。MQTT ライブラリーによっては、ブラウザー上では TCP ソケットによる接続をサポートしていない場合があります。

その他、コネクション関連で注意する点は以下のとおりです。

  • TCP ソケット上の MQTT と WebSocket 上の MQTT の両方で、使用するポート番号は HTTP/HTTPS のデフォルトポート番号 80、443 ではない点に注意が必要です。特に、社内環境での利用を想定する場合などはファイアウォールなどネットワークの設定にご注意ください。Kii Cloud で使用するポート番号は ネットワーク環境 をご覧ください。

  • コネクションが切れた場合の動作はライブラリーの実装次第です。開発するアプリの仕様として FCM/APNs のように継続的な接続を期待する場合は、再接続の処理を明示的に実装しなければならない場合があります。