Topic Alias is a way to reduce PUBLISH packet size.
There are two independent Topic Alias capacities.
sequenceDiagram
Note left of client1: prepare 10 capacity
client1->>broker: CONNECT TopicAliasMaximum=10
Note right of broker: broker can send 1-10 TopicAlias to client1
Note right of broker: prepare 20 capacity for client1
broker->>client1: CONNACK TopicAliasMaximum=20
Note left of client1: client1 can send 1-20 TopicAlias to the broker
The client can set the Topic Alias Maximum
property to a value greater than 0 in the CONNECT packet. This means the client can receive PUBLISH packets with the Topic Alias
property set to a value less than or equal to the Topic Alias Maximum
. The broker can then send PUBLISH packets using the Topic Alias
property.
If the broker does not receive a CONNECT packet with the Topic Alias Maximum
property set to a value greater than 0, the broker cannot use Topic Alias
.
The broker can set the Topic Alias Maximum
property to a value greater than 0 in the CONNACK packet. This means the broker can receive PUBLISH packets with the Topic Alias
property set to a value less than or equal to the Topic Alias Maximum
. The client can then send PUBLISH packets using the Topic Alias
property.
If the client does not receive a CONNACK packet with the Topic Alias Maximum
property set to a value greater than 0, the client cannot use Topic Alias
.
sequenceDiagram
Note right of client1: Register
client1->>broker: PUBLISH TopicName=topic1, TopicAlias=1
Note right of client1: Use
client1->>broker: PUBLISH TopicName="", TopicAlias=1
Note right of broker: Extract topic1 from TopicAlias 1
Note right of client1: Register(Overwirte)
client1->>broker: PUBLISH TopicName=topic2, TopicAlias=1
Note right of client1: Use
client1->>broker: PUBLISH TopicName="", TopicAlias=1
Note right of broker: Extract topic2 from TopicAlias 1
When you set the TopicName
filed and Topic Alias
property in the PUBLISH packet, the mapping is registered. If the Topic Alias
is already mapped, the mapping is overwritten.
If you are using async_mqtt as the client, all you need to do is set the Topic Alias Maximum
property in the CONNECT packet.
If you are using async_mqtt as the server (broker), all you need to do is set the Topic Alias Maximum
property in the CONNACK packet.
Then the mapping functionality is automatically set up.
When you call this function with the argument true
, the Topic Alias
is automatically allocated and used when you send a PUBLISH packet. If you run out of all Topic Alias
values, the oldest mapping is automatically replaced using the LRU (Least Recently Used) algorithm.
When you call this function with the argument true
, the Topic Alias
is automatically used if the mapping is registered when you send a PUBLISH packet.
async_mqtt has already solved this problem. This is an implementation note.
If the client/broker keeps the session, any halfway QoS1 and QoS2 PUBLISH packets should be resent just after reconnection. What happens if the PUBLISH packet uses a Topic Alias
? In this case, the TopicName
is empty. The counterpart’s Topic Alias Maximum
could be reduced (or removed) upon reconnection. The MQTT spec states that the lifetime of a Topic Alias
mapping should end on disconnect. In other words, the lifetime of a Topic Alias
mapping is the same as the lifetime of the connection, not the session.
So, if the client/broker sends a PUBLISH packet with an empty TopicName
and Topic Alias
property just after reconnection, it is a protocol violation.
To solve this problem, the client/broker needs to extract the TopicName
from the Topic Alias
property when sending and create a new PUBLISH packet containing the extracted TopicName
, and remove the Topic Alias
property from the sending PUBLISH packet. When resending, use the stored (non-Topic Aliased) packet.
This process is automatically handled by async_mqtt internally. Users don’t need to worry about this issue.
sequenceDiagram
client1->>broker: CONNECT SessionExpiryInterval=0xffffffff(inifinity)
broker->>client1: CONNACK SessionPresent=0
Note right of client1: Register
client1->>broker: PUBLISH TopicName=topic1, TopicAlias=1
Note right of client1: Use
client1->>broker: PUBLISH TopicName="", QoS=1, TopicAlias=1
Note right of client1: Connection closed before PUBACK is received, but the session is keeping by the broker
client1->>broker: CONNECT CleanStart=0
broker->>client1: CONNACK SessionPresent=1
Note right of client1: This is a protocol error because TopicAlias is no registered on this conneciton
client1->>broker: PUBLISH TopicName="", QoS=1, TopicAlias=1
Note right of client1: If client1 doesn't resend the packet, it is QoS=1 (At least once) violation
Note right of client1: Expected behavior is resending the following packet.
client1->>broker: PUBLISH TopicName=topic1, QoS=1
async_mqtt does expected behavior automatically.