0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MQTT5 Topic Aliasについて

Last updated at Posted at 2025-12-15

Topic Alias

 Topic AliasはPublishで送信するトピックにエイリアスを設定することができる機能です。mqtt5で追加されました。

エイリアス(alias)とは, 別名、通称のこと

メリットとして、何度も使うトピックに対して、1回目の送信でエイリアスを設定することで、それ以降、送信する際のパケット容量を節約することができます。
サーバー、クライアント双方で受け入れ可能なTopic Aliasの最大値はConnect/Connackのvariable header/Properties/Topic Alias Maximumに乗せて取り交わします。

実践

サーバ側:

  • サーバからのTopic Alias Maximumを確認します
  • クライアントからもTopic Alias Maximumとして受け入れ可能な最大値5を設定します
  • 最初のPublishにプロパティとしてTopicAliasを設定すると、それ以降、Topicに何も設定しなくてもTopicAliasに番号を設定するだけで、設定したトピック(test/topic)として送信できるはずです
topicalias.py
import paho.mqtt.client as mqtt
from paho.mqtt.properties import Properties
from paho.mqtt.packettypes import PacketTypes
import threading
import time

BROKER = "localhost"
TOPIC = "test/topic"
TOPIC_ALIAS = 1

# ============================
# Subscriber
# ============================
def on_message(client, userdata, msg):
    print(f"[受信] {msg.topic}: {msg.payload.decode()}")


def on_connect_sub(client, userdata, flags, reason_code, properties):
    print("[Subscriber CONNACK] Connected")

    # TopicAliasMaximum を安全に取得
    max_alias = getattr(properties, "TopicAliasMaximum", None)
    if max_alias is None:
        print("  サーバは TopicAliasMaximum を返さなかった")
    else:
        print(f"  サーバが受け入れる TopicAliasMaximum = {max_alias}")


def subscriber():
    # CONNECT プロパティ(Subscriber が受信可能な TopicAlias の最大値)
    sub_props = Properties(PacketTypes.CONNECT)
    sub_props.TopicAliasMaximum = 10

    print(f"[Subscriber CONNECT] TopicAliasMaximum={sub_props.TopicAliasMaximum}")

    sub = mqtt.Client(
        client_id="sub-client",
        protocol=mqtt.MQTTv5,
        callback_api_version=mqtt.CallbackAPIVersion.VERSION2
    )
    sub.on_connect = on_connect_sub
    sub.on_message = on_message

    sub.connect(BROKER, 1883, 60, properties=sub_props)
    sub.subscribe(TOPIC)
    sub.loop_forever()


# ============================
# Publisher
# ============================
def on_connect_pub(client, userdata, flags, reason_code, properties):
    print("[Publisher CONNACK] Connected")

    max_alias = getattr(properties, "TopicAliasMaximum", None)
    if max_alias is None:
        print("  サーバは TopicAliasMaximum を返さなかった(MQTT 3.1.1 / 未対応)")
    else:
        print(f"  サーバが受け入れる TopicAliasMaximum = {max_alias}")


def publisher():
    # CONNECT プロパティ(Publisher 側の TopicAliasMaximum)
    pub_props = Properties(PacketTypes.CONNECT)
    pub_props.TopicAliasMaximum = 5

    print(f"[Publisher CONNECT] TopicAliasMaximum={pub_props.TopicAliasMaximum}")

    pub = mqtt.Client(
        client_id="pub-client",
        protocol=mqtt.MQTTv5,
        callback_api_version=mqtt.CallbackAPIVersion.VERSION2
    )
    pub.on_connect = on_connect_pub

    pub.connect(BROKER, 1883, 60, properties=pub_props)

    # ---- ① 最初の Publish(Topic + Alias で登録) ----
    props = Properties(PacketTypes.PUBLISH)
    props.TopicAlias = TOPIC_ALIAS

    first_msg = "First Hello (with Topic)"
    pub.publish(TOPIC, first_msg, qos=0, properties=props)
    print(f"[送信] {first_msg} (Topic付き / Alias={TOPIC_ALIAS})")

    time.sleep(1)

    # ---- ② 2回目以降(Topic="" + Alias) ----
    for i in range(3):
        props2 = Properties(PacketTypes.PUBLISH)
        props2.TopicAlias = TOPIC_ALIAS

        msg = f"Hello by Alias {i}"
        pub.publish("", msg, qos=0, properties=props2)
        print(f"[送信] {msg} (Topicなし / Alias={TOPIC_ALIAS})")
        time.sleep(1)

    pub.disconnect()


# ============================
# Main
# ============================
if __name__ == "__main__":
    # Subscriber(常時受信)
    t = threading.Thread(target=subscriber, daemon=True)
    t.start()

    # Subscriber 接続後に Publisher 実行
    time.sleep(1)
    publisher()

    time.sleep(2)

[~/qiita/client]$uv run topicalias.py
[Subscriber CONNECT] TopicAliasMaximum=10
[Subscriber CONNACK] Connected
  サーバは TopicAliasMaximum を返さなかった
[Publisher CONNECT] TopicAliasMaximum=5
[送信] First Hello (with Topic) (Topic付き / Alias=1)
[受信] test/topic: First Hello (with Topic)
[送信] Hello by Alias 0 (Topicなし / Alias=1)
[受信] : Hello by Alias 0
[送信] Hello by Alias 1 (Topicなし / Alias=1)
[受信] : Hello by Alias 1
[送信] Hello by Alias 2 (Topicなし / Alias=1)
[受信] : Hello by Alias 2
[~/qiita/client]$
  • トピックなしでもAliasを設定して送信できることが確認できました
  • TopicAliasMaximumは実験で使用したブローカー(mochi-co)では設定されていませんでした

まとめ

Topic Aliasについて確認し、実際に使ってみました。IoTの場面では容量を節約できるのは嬉しい場合があるのではないでしょうか?

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?