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+

MQTTとMessagePub+ 目次に戻る

※この記事に掲載されている内容、および製品仕様、所属情報(会社名・部署名)は公開当時のものです。予告なく変更される場合がありますので、あらかじめご了承ください。

関連サービス