MQTTv5には、プロパティが実装されました。
プロパティとは、データ本体(ペイロード)を修飾する情報です。HTTPのヘッダのような位置づけになります。AWS IoT Core(以下、IoT Core) は MQTTv5 に対応しており、プロパティを扱うことができます。
MQTTv5のプロパティ(property)を、Eclipse MosquittoとAWS IoT Coreで使ってみました。
MQTTv5 のプロパティ
MQTTv5 のプロパティには、MQTTv5で既定されたプロパティと、ユーザーが自由に設定できるプロパティ(ユーザープロパティ)の2種類があります。
既定プロパティには、ペイロードのフォーマットを表す "Content Type" や、サブスクライブ側での処理結果を返して欲しいトピックを示唆する "Response Topic" といったものがあります。ユーザープロパティはキー名と値を指定します。
既定プロパティについては MQTTv5 properties や mosquitto の properties をご覧ください。
AWS IoT Core を MQTT ブローカー(サーバー)として、クライアント間でプロパティを扱う
IoT Coreは MQTTブローカー(サーバー)として動作します。ここではIoT Coreに接続した2つのMQTTクライアント間で、トピック my/topic
に、データ= {"v1":1}
と共に、ユーザープロパティ key = KEY1
value = VALUE1
を Publish/Subscribe の様子を見てみます。
AWS IoT Core との通信は MQTTS(MQTT+TLS) です。暗号化通信に使う X.509 証明書はAWS IoT クライアント証明書を作成するで作成しています。
mosquitto_pub -V 5 -d -i a2 -h foobar-ats.iot.us-east-2.amazonaws.com -p 8883 \
--cafile AmazonRootCA1.pem --cert 99a6e4b-certificate.pem.crt --key 99a6e4b-private.pem.key \
-t my/topic -m '{"v1":1}' --property PUBLISH user-property KEY1 VALUE1
サブスクライブ側では以下の通りです。
mosquitto_sub -V 5 -d -i a1 -h foobar-ats.iot.us-east-2.amazonaws.com -p 8883 \
--cafile AmazonRootCA1.pem --cert fb76055-certificate.pem.crt --key fb76055-private.pem.key \
-t my/topic -F "%j" --pretty
{
"tst": "2022-12-16T23:27:57.854315Z+0900",
"topic": "my/topic",
"qos": 0,
"retain": 0,
"payloadlen": 8,
"properties": {
"user-properties": {
"KEY1": "VALUE1"
}
},
"payload": "{\"v1\":1}"
}
データ本体である payload とは別に、properties がKey-Valueの形で受け取れています。
既定プロパティの "Response Topic" の指定時は以下の通りです。
mosquitto_pub -V 5 -d -i a2 -h foobar-ats.iot.us-east-2.amazonaws.com -p 8883 \
--cafile AmazonRootCA1.pem --cert 99a6e4b-certificate.pem.crt --key 99a6e4b-private.pem.key \
-t my/topic -m '{"v1":1}' --property PUBLISH response-topic "foo/bar"
mosquitto_sub -V 5 -d -i a1 -h foobar-ats.iot.us-east-2.amazonaws.com -p 8883 \
--cafile AmazonRootCA1.pem --cert fb76055-certificate.pem.crt --key fb76055-private.pem.key \
-t my/topic -F "%j" --pretty
{
"tst": "2022-12-16T23:27:53.983234Z+0900",
"topic": "my/topic",
"qos": 0,
"retain": 0,
"payloadlen": 8,
"properties": {
"response-topic": "foo/bar"
},
"payload": "{\"v1\":1}"
}
プロパティはあくまでも「ヒント」ですので、Content Type や Response Topic といったプロパティの値を採用するか否かは受信側の実装となります。
AWSブログで紹介されている "Request/Response pattern" というのは、Response Topic を使ったパターンということになります。
プロパティは AWS IoT Core のルール内で参照可能
プロパティは AWS IoT Core のルール内で参照できます。読み出しには2つの関数があります。
-
get_mqtt_property(name):
response-topic
等、MQTTv5 の既定プロパティを読み出す- 例)
get_mqtt_property("response_topic")
- 例)
-
get_user_properties(userPropertyKey):
user-property
を対象に読み出す- 例)
get_user_properties("KEY1")
- 例)
AWSブログでは Conetnt Type が Base64 だったら decode() 関数を通すという実装例が紹介されています。
おわりに
こういった「域外通信」には、以下のようにペイロード内に _header
のような項目を入れて実装していたかと思いますが、これが無くせるというのは実装の見通しが良くなりそうですね。
{
"data": "djE9MSx2Mj0iZm9vYmFyIgo=",
"_header": {
"content-type": "base64",
"response-topic": "foo/bar"
}
}
MQTTv5 はプロパティ以外にも、2回目以降のTopic指定文字列を削減できるトピックエイリアスといった実装に有利な機能が入っています。Eclipse Mosquittoも、かなり率先して追従してますので、まずはコマンドラインで試してみるのはいかがでしょうか。
EoT