# MQTT : v3.1.1 — Overview
## Overview
### Timeline
- 1999 — created
- 2012 — Mosquitto v1.0 released
- 2013 — HiveMQ founded
- 2014 — v3.1.1 published
- 2018 — v5.0 published
### Architecture
- message protocol
- client / broker
- pub / sub
- simple, lightweight, optimized for IoT (smallest packet is two bytes)
- built on TCP/IP
- uses persistent connections
- can add TLS between TCP and MQTT
- binary, bidirectional, data-agnostic
- Google protobuffs is a popular option for data
- heartbeat mechanism
### Features
- persistent sessions
- Last Will & Testament
- per-message quality-of-service levels
- 0 -> at most once (fire & forget)
- 1 -> at least once
- 2 -> exactly once
- retained messages (for new subscribers)
- authentication
- username + password
- possibly more?
### Operations
- Connect / Disconnect
- Ping
- Pub / Sub / Unsub
### Standard Ports
**Ports:**
- 1883 -> MQTT
- 8883 -> MQTT + TLS (aka "secure-mqtt" or "mqtts")
- MQTT over WebSockets
- 9001 <- Mosquitto, with or without TLS (ws://localhost:9001/)
- 8884 <- HiveMQ Cloud with TLS (wss://foo.bar.hivemq.cloud:8884/mqtt)
- 443 is also popular
> [!NOTE] Use in Browsers
> Must use websockets (ws: or wss:) to connect to broker.
## Concepts
### Sessions
Based on arbitrary Client ID provided during connection.
**Client State:**
- QoS 1 and QoS 2 messages which have been sent to the Broker, but have not been completely acknowledged.
- QoS 2 messages which have been received from the Broker, but have not been completely acknowledged.
**Broker State:**
- The existence of a Session, even if the rest of the Session state is empty.
- The Client’s subscriptions.
- QoS 1 and QoS 2 messages which have been sent to the Client, but have not been completely acknowledged.
- QoS 1 and QoS 2 messages pending transmission to the Client.
- QoS 2 messages which have been received from the Client, but have not been completely acknowledged.
- Optionally, QoS 0 messages pending transmission to the Client.
**Clean vs Persistent**
- *Clean* — new session (and delete previous)
- *Persistent* — resume previous session if exists
Clean sessions recommended if:
- client only needs to publish, or...
- message loss is acceptable
### Topics
**Topic Names**
- utf-8, case-sensitive
- 1 <= length <= 65535
- may include any characters except Null
- hierarchial (kind of)
- slashes treated as any other character (except when applying wildcards) — "foo", "foo/", and "/foo" are all different
- you can have a leading slash, a trailing slash, a bunch of slashes in a row, etc
**Topic Filters**
- specifies a pattern of topics to subscribe that may include wildcards:
- "+" is a single-level wildcard (ex: "foo/+/bar")
- “foo/+” does not match “foo” but it does match “foo/”
- “foo/bar/+” matches “foo/bar/42” and “foo/bar/53”, but not “foo/bar/53/baz”
- "#" is a muilti-level wildcard (ex: "foo/#")
- must follow a slash and be the last character
- "foo/#" also matches "foo" because "#" includes the parent level
**Reserved Topics**
- topics starting with "
quot; are special — clients should not publish to them
- "$SYS/" has been widely adopted for server info
- wildcards will not match topics that start with "quot;
- "#" won't match `$SYS/foo`, but `$SYS/#` will
**Best Practices**
- no leading slash
- no spaces or weird chars
- shorter is better
- never sub to root!
> [!WARNING] Overlapping Subscriptions Get Weird
> Topic Filters with wildcards might overlap each other, meaning a message could match multiple subscriptions. In this case, the Broker MUST deliver the message to the Client respecting the maximum QoS of all matching subscriptions. In addition, the Broker MAY deliver further copies of the message, one for each additional matching subscription and respecting the subscription’s QoS in each case.
> [!WARNING] Wildcard Support Not Guaranteed
> Brokers are not REQUIRED to support wildcards. If they don't, they must reject SUBSCRIBE packets containing wildcards.
### Message Ordering & In-Flight Windows
Messages are sent to subscribers in the order they were published, with allowances for duplication. For example, a publisher might send messages in the order 1,2,3,4 and the subscriber might receive them in the order 1,2,3,2,3,4.
If both Client and Broker make sure that no more than one message is “in-flight” at any one time (by not sending a message until its predecessor has been acknowledged), then no QoS 1 message will be received after any later one. For example, a subscriber might receive them in the order 1,2,3,3,4 but not 1,2,3,2,3,4.
Setting an in-flight window of 1 also means that order will be preserved even if the publisher sends a sequence of messages with different QoS levels on the same topic.
### Quality of Service
The QoS of messages sent in response to a Subscription MUST be the minimum of:
- the QoS of the originally published message
- the maximum QoS granted by the Broker
The server is permitted to send duplicate copies of a message to a subscriber in the case where the original message was published with QoS 1 and the maximum QoS granted was QoS 0.
If the subscribing Client has been granted maximum QoS 0, then a message originally published as QoS 2 might get lost on the hop to the Client, but the Broker should never send a duplicate of that Message. A QoS 1 message published to the same Topic might either get lost or duplicated on its transmission to that Client.
Subscribing to a Topic Filter at QoS 2 is equivalent to saying: "I would like to receive messages matching this filter at the QoS with which they were published". This means a publisher is responsible for determining the maximum QoS a message can be delivered at, but a subscriber is able to require that the Broker downgrades the QoS to one more suitable for its usage.
## References
- https://mqtt.org/mqtt-specification/
- https://hivemq.com/mqtt/
- https://emqx.com/en/blog/the-easiest-guide-to-getting-started-with-mqtt