この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
CX 事業本部のデリバリー部の平内(SIN)です。
AWS re:Invent 2022 で発表された、AWS IoT Core での MQTT v5 対応に反応して、色々入門しています。
今回は、MQTT v5 が返す応答に含まれるレスポンスコードについて確認してみました。
なお、現時点(2022/11/30)では、AWS で提供される SDK は、MQTT v5 に対応していないため、サンプル作成には、paho.mqtt を使用させて頂きました。
参考:https://dev.classmethod.jp/articles/aws-iot-core-mqtt-v5-sdk-for-python
2 レスポンスコード
MQTT v3.1 では、正常系、異常系ともに、必要最低限の情報以外の情報を返すことはできませんでしたが、MQTT v5 になってレスポンスコードにより、応答(Sussecc/Error)の理由が詳細に表現されるようになりました。
AWS IoT Core では、以下の Response Code が定義されています。
Value | Hex | Reason Codename | Command |
---|---|---|---|
0 | 0x00 | Success, Granted QoS 0 | CONNACK , PUBLISH, SUBACK, UNSUBACK |
1 | 0x01 | Granted QoS 1 | SUBACK |
2 | 0x02 | Granted QoS 2 | SUBACK |
128 | 0x80 | Unspecified error | CONNACK , PUBLISH, SUBACK, UNSUBACK |
129 | 0x81 | Malformed Packet | DISCONNECT |
130 | 0x82 | Protocol Error | DISCONNECT |
133 | 0x85 | Client Identifier not valid | CONNACK |
134 | 0x86 | Bad User Name or Password | CONNACK |
135 | 0x87 | Not authorized | CONNACK , PUBLISH, DISCONNECT, SUBACK |
139 | 0x8B | Server shutting down | DISCONNECT |
141 | 0x8D | Keep Alive timeout | DISCONNECT |
142 | 0x8E | Session taken over | DISCONNECT |
143 | 0x8F | Topic Filter invalid | DISCONNECT ,SUBACK, UNSUBACK |
144 | 0x90 | Topic Name invalid | CONNACK , PUBLISH, DISCONNECT |
145 | 0x91 | Packet identifier in use | PUBLISH ,SUBACK, UNSUBACK |
147 | 0x93 | Receive Maximum exceeded | DISCONNECT |
148 | 0x94 | Topic Alias invalid | DISCONNECT |
151 | 0x97 | Quota exceeded | CONNACK , PUBLISH ,DISCONNECT ,SUBACK |
152 | 0x98 | Administrative action | DISCONNECT |
155 | 0x9B | QoS not supported | CONNACK , DISCONNECT |
161 | 0xA1 | Subscription Identifiers not supported | DISCONNECT |
https://docs.aws.amazon.com/iot/latest/developerguide/mqtt.html#mqtt5
3 実装例
以下が、実装したコードです。
Connect の後、Topic Alias を指定して、3 回の publish を行っています。
import ssl
import os
import time
import paho.mqtt.client as mqtt
from paho.mqtt.properties import Properties
from paho.mqtt.packettypes import PacketTypes
endpoint = "xxxxxxxxxxxx-ats.iot.ap-northeast-1.amazonaws.com"
port = 8883
dir = os.path.dirname(os.path.abspath(__file__))
certs = {
"cafile": "{}/certificates/AmazonRootCA1.pem".format(dir),
"certfile": "{}/certificates/client-cert.pem".format(dir),
"keyfile": "{}/certificates/private-key.pem".format(dir),
}
def on_connect(client, user_data, flags, reason_code, properties=None):
print("on_connect")
def on_publish(client,userdata, result,properties=None):
print("on_publish")
def on_disconnect(mqttc, user_data, reason_code, properties=None):
print("on_disconnect reason: {}".format(reason_code))
exit()
def main():
client = mqtt.Client("client_id", protocol = mqtt.MQTTv5)
client.tls_set(certs["cafile"],
certfile=certs["certfile"],
keyfile=certs["keyfile"],
cert_reqs=ssl.CERT_REQUIRED,
tls_version=ssl.PROTOCOL_TLSv1_2,
ciphers=None)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish
client.connect(endpoint, port, properties = None)
client.loop_start()
time.sleep(1)
properties = Properties(PacketTypes.PUBLISH)
topic = "sensors/device1"
payload = "message"
# 1回目のpublish (Topic Alias = 7)
properties.TopicAlias = 7
client.publish(topic, payload, qos=1, properties=properties)
time.sleep(1)
# 2回目のpublish (Topic Alias = 8)
properties.TopicAlias = 8
client.publish(topic, payload, qos=1, properties=properties)
time.sleep(1)
# 3回目のpublish (Topic Alias = 9)
properties.TopicAlias = 9
client.publish(topic, payload, qos=1, properties=properties)
time.sleep(1)
if __name__ == "__main__":
main()
この時のログ出力は、以下のようになります。
% python3 index.py
on_connect
on_publish
on_publish
on_disconnect reason: Topic alias invalid
AWS IoT Core では、Topic Alias の制限(デフォルト値)が、8なので、8以上を指定した 3 回目の publish は、成功せず、connect自体が切断されています。 そして、disponnect 時に、その切断理由「Topic alias invalid」が、reason_code で確認できています。
なお、エラー事由は、AWS IoT Core から返ってきているものであり、特に何か実装しているわけではありません。
4 最後に
Reason Code の一覧を見ると、とりわけ異常系において、失敗の理由が各種定義されているため、この Reason Code を利用して実装することで、エラー処理がよりシンプルかつ、漏れなく記述できるようになりそうです。
なお、拡張されたプロパティ領域の、User Propertyで、こちらでシステム固有の理由などを返すことも有効でしょう。 [AWS IoT Core] MQTT v5 を使用してユーザープロパティを実装して見ました
5 参考リンク
Introducing new MQTTv5 features for AWS IoT Core to help build flexible architecture patterns
[AWS IoT Core] MQTT v5 を使用してリクエスト・レスポンス パターンを実装して見ました
[AWS IoT Core] MQTT v5 を使用してユーザープロパティを実装して見ました
[AWS IoT Core] MQTT v5 を使用してトピック・エイリアスを実装して見ました
[AWS IoT Core] MQTT v5 を使用してメッセージ及び、セッション有効期限とクリーンスタートを実装して見ました