MQTTとMessagePub+ :MessagePub+ におけるセッション管理
MQTTブローカーにクライアントを接続する際、次のようなことを考える必要があります。
- MQTTの下位の通信プロトコルは何を用いるのか
- MQTTのプロトコルバージョンは何にするのか
- 切断後、再接続した時、切断前の状態を継承するのか
それぞれ、どういった選択肢があるのかは、MQTTブローカーによって異なります。
ここでは、MessagePub+ ブローカーに関してそれぞれ説明します。
サポートする通信プロトコル
MessagePub+ ブローカーがサポートする通信プロトコルは以下の通りです。
プロトコル | 一般的な用途 |
---|---|
MQTT | 暗号化されないMQTT接続。セキュアなネットワーク内でのMQTT通信に用いる。 |
MQTTS | TLSで暗号化されたMQTT接続。インターネットを介したMQTT通信などで用いる。 |
MQTT on WebSocket(ws) | 暗号化されないWebSocket上でのMQTT接続。セキュアなネットワーク内でのWebブラウザによるMQTT通信に用いる。 |
MQTT on wss | TLS暗号化されたWebSocket(wss)上でのMQTT接続。インターネットを介したWebブラウザによるMQTT通信に用いる。 |
HTTP(REST) | 暗号化されないHTTP(REST)接続。メッセージのPOST/GETを行うことができる。MQTTとHTTPの混在環境で用いる。 |
HTTPS(REST) | TLS暗号化されたHTTPS(REST)接続。メッセージのPOST/GETを行うことができる。MQTTとHTTPの混在環境で用いる。 |
選択の際、まず考えるポイントは、TLS暗号化が必要か否かです。暗号化が必要な場合、MQTTS,MQTT on wss, HTTPS(REST)が選択肢となり、不要な場合は、MQTT,MQTT on WebSocket(ws), HTTP(REST)が選択肢となります。次に、通信する環境を考えます。Webブラウザ上で動作する必要があるなら、MQTT on WebSocket(ws),MQTT on wssが選択肢となります。そうでなければ、MQTT,MQTTSを選択すると良いでしょう。なお、HTTP(REST)とHTTPS(REST)は、MQTT通信ではありません。既存のREST APIしかサポートしないデバイスがあり、それをMQTTと連動させたい時に用いることができます。
MQTT接続
MQTTには、プロトコルバージョンがあり、MessagePub+ ブローカーは、3.1.1および5.0をサポートしています。それぞれのバージョンで接続するクライアントを混在させること可能で、相互にメッセージをやり取りすることも可能です。
MessagePub+ ブローカーに接続するクライアントは、MQTTのCONNECTパケットの、UserName, ClientIdentifier, Passwordを適切に設定する必要があります。設定方法を説明する前に、MessagePub+ の認証について説明します。
要素 | 意味 |
---|---|
app | userが存在する名前空間。userがファイルだとすれば、フォルダーのイメージ。事前登録が必要※1。 |
user | 認証、認可の単位。同一app内でユニーク。例えばapp a1のなかにuser u1はひとつしか存在できない。なお、app a2のなかにuser u1が存在するのは問題ない。a1のu1とa2のu1は、別のuserとして扱われる。事前登録が必要※1。 |
session | 同一userを複数ブローカーに接続したい時に設定する文字列。事前登録不要。認証、認可はuserによって行われるのでsessionが異なるがuserは同一の接続は、全く同じ認証、認可となる。ただし、接続自体は完全に別なので、サブスクライブやパブリッシュが共通になることはない。 |
token | appとuserを認証するためのパスワード。有効期限を設定することができる。複数のtokenをひとつのapp-userに設定することができる。事前登録が必要※1。 |
※1 事前登録とは、MessagePub+ ブローカーに管理者モードなどで接続することで、userなどの登録や削除を行うことを指します。
MessagePub+ では、app, user, sessionによって接続を識別します。これらが全て同じクライアントを接続した場合で、既に接続されている同一クライアントがあった場合、そのクライアントは切断され、新しい接続が有効になります。いわゆる後勝ち動作となります。
これを踏まえ、接続を行います。接続においては、MQTTのCONNECTパケットを以下のように設定します。ClientIdentifierに情報を設定する方法と、UserNameに情報を設定する方法があります。お使いのMQTTクライアントによっては、設定に制約がある場合がありますが、大抵のクライアントで、いずれかの方法で接続できると思います。
指定内容/CONNECTパケット要素 | UserName | ClientIdentifier | Password | 備考 |
---|---|---|---|---|
app user session指定 | - | user@app%session | token | |
app user session指定 | user@app%session | - | token | |
app user session指定 | user@app | session | token | |
app user指定 | - | user@app | token | sessionは空文字列として指定される |
app user指定 session生成要求 | user@app | - | token | sessionはbrokerでユニークに生成される |
sessionをbrokerでユニークに生成した場合、MQTTのプロトコルバージョンが5.0の場合、CONNECTパケットの応答としてブローカーからクライアントに送られるCONNACKパケットのAssignedClientIdentifierプロパティにuser@app%生成されたsessionという文字列が設定されます。これにより、クライアントは生成されたsessionを知ることができます。一方MQTTのプロトコルバージョンが3.1.1の場合、プロパティという仕組みが存在しないため、クライアントは生成されたsessionを知ることができません。そのため、いくつか接続に制限が生じます。
何が制限されるのかを理解するために、まず、コネクション切断後のセッションの維持について説明します。
コネクション切断後のセッションの維持
MQTTでは、CONNECTパケットによってコネクションを開始し、DISCONNECTパケットや、その他切断によってコネクションが終了します。その後、再接続(app, user, sessionが同一のクライアントを再度接続すること)した際、これまでの接続を継承することが可能です。この、コネクションを跨いで継承される情報のことをセッションと呼びます。セッションは、app, user, sessionで一意に識別されます。セッションには、サブスクライブ情報、QoS1とQoS2の送りかけPUBLISHパケット情報、QoS2の送りかけPUBRELパケット情報が含まれます。セッションを継承した場合、接続後にサブスクライブは自動的に復活し、送りかけのパケットは自動的に(再)送信されます。
コネクションを跨いでセッションを継承するには、切断前後の接続におけるCONNECTパケットを適切に設定する必要があります。MQTTのプロトコルバージョン3.1.1では、切断前後の接続それぞれが、CleanSessionフラグを 0 に指定する必要があります。切断中のサブスクライブ情報は保持され、送りかけのPUBLISHおよびPUBRELパケットは再接続時に再送されます。さらに、サブスクライブ状態にあるトピックに、切断中に他のクライアントからパブリッシュが行われた場合、再接続時にそのパブリッシュされたメッセージをクライアントに配信します。なお、切断中のセッションをいつまで維持するかについては、MQTTブローカーによって上限が定められているのが一般的です。MessagePub+ ブローカーの場合、上限を起動オプションで設定可能で、これにより、リソース消費し過ぎないようになっています。
プロトコルバージョン5.0では、切断前の接続で、SessionExpiryIntervalプロパティを1以上の値に指定しておき、切断後の接続でCleanStartフラグを 0 に指定する必要があります。保持される情報などについては、プロトコルバージョン3.1.1と同様です。切断中のセッションをいつまで維持するかについては、切断後SessionExpiryIntervalプロパティで指定された秒数が経過するまでの間となります。ただし、ブローカーの起動オプションで設定した保持期限よりも長い秒数がSessionExpiryIntervalプロパティで指定された場合、ブローカー起動オプションで設定された保持期限が優先されます。
MQTTプロトコルバージョン3.1.1の制限
MQTTプロトコルバージョン3.1.1で接続したクライアントが、session生成要求をMessagePub+ ブローカーに対して行った場合、ブローカーは重複しないsessionを生成しますが、それをクライアントに伝える手段がないことは、前述の通りです。これは、クライアントが再接続することができないことを意味します。なぜなら、クライアント側では、app, userは分かっても、生成されたsessionが分からないためです。よってMessagePub+ ブローカーは、MQTT プロトコルバージョンが3.1.1で、session生成要求を行うようにUserName, ClientIdentifierを設定し、かつ、CleanSessionフラグが0の接続を拒否します。これが、プロトコルバージョン3.1.1の制限です。プロトコルバージョン5.0にはこのような制限はありません。
MQTTとMessagePub+
※この記事に掲載されている内容、および製品仕様、所属情報(会社名・部署名)は公開当時のものです。予告なく変更される場合がありますので、あらかじめご了承ください。
関連サービス
-
IoTメッセージングプラットフォーム「MessagePub+」
MessagePub+ はオージス総研が開発したつなげることに特化した"IoTメッセージングプラットフォーム"です
関連記事一覧
MQTTとHTTPの違い。IoT開発に使用するプロトコルはどのように選ぶべきか?
MQTTがIoTに最適な理由とは?知っておくべきMQTTの基本と導入メリット
MQTTとMessagePub+ :ラベル(MessagePub+ )
MQTTとMessagePub+ :トピックの名前と階層化
MQTTとMessagePub+ :トピック分類のまとめ
MQTTとMessagePub+ :応答系トピック
MQTTとMessagePub+ :要求系トピック
MQTTとMessagePub+ :通知系トピック
MQTTとMessagePub+ :トピックの分類
MQTTとMessagePub+ :MQTTを用いたIoTサービスにおけるトピック設計
MQTTとMessagePub+ :MQTT活用のコツ