# MQTT / Mosquitto-HOWTO Author: rossano at gmail dot com Timestamp: Sat 3 Jun 09:07:57 BRT 2017 Platform: - Linux Distribution: Raspbian 8.0 - Hardware: Raspberrypi 2 MQTT Version: 3.1.1 (Reference to version 5.0 at the end) ## 0. MQTT / Mosquitto architecture overview (you can skip this part if you know what MQTT and mosquitto are and how they work) Mosquitto is a message broker that "speakes" MQTT. MQTT stands for Message Queue Telemetry Transport, which is an "open source" protocol for constrained devices and low-bandwidth, high-latency networks. It's considered an application protocol in TCP/IP model as it uses TCP as a transport protocol. MQTT uses the publish/subscribe model (as opposed to the request/response model seen in HTTP). The following figure illustrates a high-level view of the MQTT architecture: PUBLISHERS BROKER SUBSCRIBERS +--------------------------------+ [subjectD/msg] | Mosquitto Server (MQTT Broker) | [subjectD/msg] publisherA --------------> | +---------------------------+ | ----------------> subscriberX .... | | subjectD subscribers: X,Y | | [subjectD/msg] .... | +---------------------------| | ----------------> subscriberY publisherN --------------> | | subjectE subscribers: Z | | [subjectE/msg] | +---------------------------+ | ----------------> subscriberZ +--------------------------------+ MQTT also offers what is known as QoS (Quality of Service) - not to be confused with "network QoS", which has a totally different purpose. MQTT QoS values are: - **qos 0**: At most once - best effort delivery: a message will not be acknowledged by the receiver (broker) nor stored and redelivered by the sender. - **qos 1**: At least once: it's garanteed that the msg will be delivered at least once to the receiver (broker) - sender keep msg until it receives a PUBACK from receiver (broker). - **qos 2**: Garanteed that one, and only one, message will be delivered: this is the most reliable qos level and also the slowest. For each published message it is exchanged 4 MQTT messages: PUBLISH, PUBREC, PUBREL, and PUBCOMP. In order to get the total number of messages exchanged you must consider the TCP control messages such as the 3-way handshake, acks, reset, and finish (There is a "version" of MQTT that is supposed to use UDP instead of TCP to make it really lightweight).. The following sequence diagram illustrates the message exchanges between SUBSCRIBER and BROKER during the SUBSCRIPTION procedure with QOS 0 (I'll ommit TCP control messages such as the 3-way handshake and acks). SUBSCRIBER BROKER | [connect/1] | |------------------------>>| | | | [conn ack/2] | |<<------------------------| | | | [subscribe/8] | |------------------------>>| | | | [subscribe ack/9] | |<<------------------------| | | The following sequence diagram illustrates the message exchanges between PUBLISHER and BROKER during the PUBLISH procedure with QOS 0 (I'll ommit TCP control messages such as the 3-way handshake and acks) PUBLISHER BROKER | [connect/1] | |------------------------------>>| | | | [conn ack/2] | |<<------------------------------| | | | [publish/3] | |------------------------------>>| | | The following sequence diagram illustrates the message exchanges between BROKER and SUBSCRIBER during the MESSAGE FORWARDING procedure with QOS 0. (I'll ommit TCP control messages such as the 3-way handshake and acks). BROKER SUBSCRIBER X SUBSCRIBER Y | [publish/3] | | |------------------------------------>>| | | | | | [publish/3] | | |--------------------------------------+------------------------->>| | | | ## PART 1. MOSQUITTO INSTALLATION 1.1. Install mosquitto MQTT server apt-get install mosquitto 1.2. Install mosquitto MQTT command line client(s) apt-get install mosquitto_clients 1.3. Run mosquitto systemctl start mosquitto 1.4. Enable mosquitto at boot systemctl enable mosquitto ## PART 2. MOSQUITTO TESTS 2.1. Verify if mosquitto message broker is running systemctl status mosquitto :::warning If it's not running, try executing the command: `systemctl start mosquitto` ::: 2.2. Client subscription mosquitto_sub -v -t 'topic/test' 2.3. Client publication mosquitto_pub -t 'topic/test' -m 'helloWorld' You can see the message appearing at the terminal running `mosquitto_sub` (item 2.2) ## PART 3. MQTT/TCP analysis MQTT has the following header (simplified version) bits 7 6 5 4 3 2 1 0 +-------+-------+-------+-------+-------+-------+-------+-------+ | Message type | DUP | QoS | Retain| +-------+-------+-------+-------+-------+-------+-------+-------+ | Remaining length | +-------+-------+-------+-------+-------+-------+-------+-------+ Message type: - Reserved : 0 - CONNECT : 1 - SUBSCRIBE : 8 - CONNACK : 2 - SUBACK : 9 - PUBLISH : 3 - UNSUBSCRIBE : 10 - PUBACK : 4 - UNSUBACK : 11 - PUBREL : 5 - PINGREQ : 12 - PUBCOMP : 6 - PINGRESP : 13 - DISCONNECT : 14 - Reserved : 15 The following lines show the messages exchanged between clients (publisher/subscriber) and broker (captured by tcpdump). ### 3.1. SUBSCRIPTION (CONNECTION + SUBSCRIBE) ============================================================================= >>> 3-way handshake between a client and the broker ``` 11:49:37.524070 IP localhost.59238 > localhost.1883: Flags [S], seq 4074702310,win 43690, options [mss 65495,sackOK,TS val 3854646668 ecr 0,nop,wscale 7], length 0 0x0000: 4500 003c 386a 4000 4006 0450 7f00 0001 E..<8j@.@..P.... 0x0010: 7f00 0001 e766 075b f2df 05e6 0000 0000 .....f.[........ 0x0020: a002 aaaa fe30 0000 0204 ffd7 0402 080a .....0.......... 0x0030: e5c1 3d8c 0000 0000 0103 0307 ..=......... 11:49:37.524085 IP localhost.1883 > localhost.59238: Flags [S.], seq 3528818720, ack 4074702311, win 43690, options [mss 65495,sackOK,TS val 3854646668 ecr 3854646668,nop,wscale 7], length 0 0x0000: 4500 003c 0000 4000 4006 3cba 7f00 0001 E..<..@.@.<..... 0x0010: 7f00 0001 075b e766 d255 8020 f2df 05e7 .....[.f.U...... 0x0020: a012 aaaa fe30 0000 0204 ffd7 0402 080a .....0.......... 0x0030: e5c1 3d8c e5c1 3d8c 0103 0307 ..=...=..... 11:49:37.524099 IP localhost.59238 > localhost.1883: Flags [.], ack 1, win 342, options [nop,nop,TS val 3854646668 ecr 3854646668], length 0 0x0000: 4500 0034 386b 4000 4006 0457 7f00 0001 E..48k@.@..W.... 0x0010: 7f00 0001 e766 075b f2df 05e7 d255 8021 .....f.[.....U.! 0x0020: 8010 0156 fe28 0000 0101 080a e5c1 3d8c ...V.(........=. 0x0030: e5c1 3d8c ..=. ``` ============================================================================= >>> Client wants to CONNECT to the broker (see byte 0x0034, first nibble is 1 - message size is seen at byte 0x0035 : 0x20 = 32 bytes) ``` 11:49:37.524131 IP localhost.59238 > localhost.1883: Flags [P.], seq 1:35, ack 1, win 342, options [nop,nop,TS val 3854646668 ecr 3854646668], length 34 0x0000: 4500 0056 386c 4000 4006 0434 7f00 0001 E..V8l@.@..4.... 0x0010: 7f00 0001 e766 075b f2df 05e7 d255 8021 .....f.[.....U.! 0x0020: 8018 0156 fe4a 0000 0101 080a e5c1 3d8c ...V.J........=. 0x0030: e5c1 3d8c 1020 0006 4d51 4973 6470 0302 ..=.....MQIsdp.. 0x0040: 003c 0012 6d6f 7371 7375 622f 3230 3032 .<..mosqsub/2002 0x0050: 362d 6173 7469 6-asti ``` >>> TCP ack from broker to client. ``` 11:49:37.524137 IP localhost.1883 > localhost.59238: Flags [.], ack 35, win 342, options [nop,nop,TS val 3854646668 ecr 3854646668], length 0 0x0000: 4500 0034 bdad 4000 4006 7f14 7f00 0001 E..4..@.@....... 0x0010: 7f00 0001 075b e766 d255 8021 f2df 0609 .....[.f.U.!.... 0x0020: 8010 0156 fe28 0000 0101 080a e5c1 3d8c ...V.(........=. 0x0030: e5c1 3d8c ..=. ``` >>> Broker responds with a CONNACK msg to the client (see byte 0x0034, first nibble is 2 - message size is seen at byte 0x0035 : 0x02 = 02 bytes) ``` 11:49:37.524232 IP localhost.1883 > localhost.59238: Flags [P.], seq 1:5, ack 35, win 342, options [nop,nop,TS val 3854646668 ecr 3854646668], length 4 0x0000: 4500 0038 bdae 4000 4006 7f0f 7f00 0001 E..8..@.@....... 0x0010: 7f00 0001 075b e766 d255 8021 f2df 0609 .....[.f.U.!.... 0x0020: 8018 0156 fe2c 0000 0101 080a e5c1 3d8c ...V.,........=. 0x0030: e5c1 3d8c 2002 0000 ..=..... ``` >>> TCP ack from client to broker. ``` 11:49:37.524239 IP localhost.59238 > localhost.1883: Flags [.], ack 5, win 342, options [nop,nop,TS val 3854646668 ecr 3854646668], length 0 0x0000: 4500 0034 386d 4000 4006 0455 7f00 0001 E..48m@.@..U.... 0x0010: 7f00 0001 e766 075b f2df 0609 d255 8025 .....f.[.....U.% 0x0020: 8010 0156 fe28 0000 0101 080a e5c1 3d8c ...V.(........=. 0x0030: e5c1 3d8c ..=. ``` ============================================================================= >>> Client wants to SUBSCRIBE to the topic "topic/test" with the broker (see byte 0x0034, first nibble is 8 - message size is seen at byte 0x0035 : 0x0f = 15 bytes) ``` 11:49:37.524258 IP localhost.59238 > localhost.1883: Flags [P.], seq 35:52, ack 5, win 342, options [nop,nop,TS val 3854646668 ecr 3854646668], length 17 0x0000: 4500 0045 386e 4000 4006 0443 7f00 0001 E..E8n@.@..C.... 0x0010: 7f00 0001 e766 075b f2df 0609 d255 8025 .....f.[.....U.% 0x0020: 8018 0156 fe39 0000 0101 080a e5c1 3d8c ...V.9........=. 0x0030: e5c1 3d8c 820f 0001 000a 746f 7069 632f ..=.......topic/ 0x0040: 7465 7374 00 test. ``` >>> Broker sends a SUBACK to the client (see byte 0x0034, first nibble is 9 - message size is seen at byte 0x0035 : 0x03 = 3 bytes) ``` 11:49:37.524284 IP localhost.1883 > localhost.59238: Flags [P.], seq 5:10, ack 52, win 342, options [nop,nop,TS val 3854646668 ecr 3854646668], length 5 0x0000: 4500 0039 bdaf 4000 4006 7f0d 7f00 0001 E..9..@.@....... 0x0010: 7f00 0001 075b e766 d255 8025 f2df 061a .....[.f.U.%.... 0x0020: 8018 0156 fe2d 0000 0101 080a e5c1 3d8c ...V.-........=. 0x0030: e5c1 3d8c 9003 0001 00 ..=...... ``` >>> TCP ack from client to broker. ``` 11:49:37.564458 IP localhost.59238 > localhost.1883: Flags [.], ack 10, win 342, options [nop,nop,TS val 3854646709 ecr 3854646668], length 0 0x0000: 4500 0034 386f 4000 4006 0453 7f00 0001 E..48o@.@..S.... 0x0010: 7f00 0001 e766 075b f2df 061a d255 802a .....f.[.....U.* 0x0020: 8010 0156 fe28 0000 0101 080a e5c1 3db5 ...V.(........=. 0x0030: e5c1 3d8c ..=. ``` ### 3.2. PUBLISHING to the broker ======================================================== >>> 3-way handshake between a client and the broker ``` 12:02:58.671297 IP localhost.59258 > localhost.1883: Flags [S], seq 3272796355, win 43690, options [mss 65495,sackOK,TS val 3855447815 ecr 0,nop,wscale 7], length 0 0x0000: 4500 003c 9fc4 4000 4006 9cf5 7f00 0001 E..<..@.@....... 0x0010: 7f00 0001 e77a 075b c312 e8c3 0000 0000 .....z.[........ 0x0020: a002 aaaa fe30 0000 0204 ffd7 0402 080a .....0.......... 0x0030: e5cd 7707 0000 0000 0103 0307 ..w......... 12:02:58.671312 IP localhost.1883 > localhost.59258: Flags [S.], seq 984655735, ack 3272796356, win 43690, options [mss 65495,sackOK,TS val 3855447815 ecr 3855447815,nop,wscale 7], length 0 0x0000: 4500 003c 0000 4000 4006 3cba 7f00 0001 E..<..@.@.<..... 0x0010: 7f00 0001 075b e77a 3ab0 a777 c312 e8c4 .....[.z:..w.... 0x0020: a012 aaaa fe30 0000 0204 ffd7 0402 080a .....0.......... 0x0030: e5cd 7707 e5cd 7707 0103 0307 ..w...w..... 12:02:58.671326 IP localhost.59258 > localhost.1883: Flags [.], ack 1, win 342, options [nop,nop,TS val 3855447815 ecr 3855447815], length 0 0x0000: 4500 0034 9fc5 4000 4006 9cfc 7f00 0001 E..4..@.@....... 0x0010: 7f00 0001 e77a 075b c312 e8c4 3ab0 a778 .....z.[....:..x 0x0020: 8010 0156 fe28 0000 0101 080a e5cd 7707 ...V.(........w. 0x0030: e5cd 7707 ..w. ``` >>> Client wants to CONNECT to the broker (see byte 0x0034, first nibble is 1 - message size is seen at byte 0x0035 : 0x20 = 32 bytes) ``` 12:02:58.671360 IP localhost.59258 > localhost.1883: Flags [P.], seq 1:35, ack 1, win 342, options [nop,nop,TS val 3855447815 ecr 3855447815], length 34 0x0000: 4500 0056 9fc6 4000 4006 9cd9 7f00 0001 E..V..@.@....... 0x0010: 7f00 0001 e77a 075b c312 e8c4 3ab0 a778 .....z.[....:..x 0x0020: 8018 0156 fe4a 0000 0101 080a e5cd 7707 ...V.J........w. 0x0030: e5cd 7707 1020 0006 4d51 4973 6470 0302 ..w.....MQIsdp.. 0x0040: 003c 0012 6d6f 7371 7075 622f 3230 3038 .<..mosqpub/2008 0x0050: 322d 6173 7469 2-asti ``` >>> TCP ack from broker to client ``` 12:02:58.671366 IP localhost.1883 > localhost.59258: Flags [.], ack 35, win 342, options [nop,nop,TS val 3855447815 ecr 3855447815], length 0 0x0000: 4500 0034 d07f 4000 4006 6c42 7f00 0001 E..4..@.@.lB.... 0x0010: 7f00 0001 075b e77a 3ab0 a778 c312 e8e6 .....[.z:..x.... 0x0020: 8010 0156 fe28 0000 0101 080a e5cd 7707 ...V.(........w. 0x0030: e5cd 7707 ..w. ``` >>> Broker responds with a CONNACK msg to the client (see byte 0x0034, first nibble is 2 - message size is seen at byte 0x0035 : 0x02 = 02 bytes) ``` 12:02:58.671459 IP localhost.1883 > localhost.59258: Flags [P.], seq 1:5, ack 35, win 342, options [nop,nop,TS val 3855447816 ecr 3855447815], length 4 0x0000: 4500 0038 d080 4000 4006 6c3d 7f00 0001 E..8..@.@.l=.... 0x0010: 7f00 0001 075b e77a 3ab0 a778 c312 e8e6 .....[.z:..x.... 0x0020: 8018 0156 fe2c 0000 0101 080a e5cd 7708 ...V.,........w. 0x0030: e5cd 7707 2002 0000 ..w..... ``` >>> TCP ack from client to broker ``` 12:02:58.671467 IP localhost.59258 > localhost.1883: Flags [.], ack 5, win 342, options [nop,nop,TS val 3855447816 ecr 3855447816], length 0 0x0000: 4500 0034 9fc7 4000 4006 9cfa 7f00 0001 E..4..@.@....... 0x0010: 7f00 0001 e77a 075b c312 e8e6 3ab0 a77c .....z.[....:..| 0x0020: 8010 0156 fe28 0000 0101 080a e5cd 7708 ...V.(........w. 0x0030: e5cd 7708 ..w. ``` >>> Client PUBLISHes the message "helloWorld" to the topic "topic/test" (see byte 0x0034, first nibble is 3 - message size is seen at byte 0x0035 : 0x16 = 22 bytes) ``` 12:02:58.671497 IP localhost.59258 > localhost.1883: Flags [P.], seq 35:59, ack 5, win 342, options [nop,nop,TS val 3855447816 ecr 3855447816], length 24 0x0000: 4500 004c 9fc8 4000 4006 9ce1 7f00 0001 E..L..@.@....... 0x0010: 7f00 0001 e77a 075b c312 e8e6 3ab0 a77c .....z.[....:..| 0x0020: 8018 0156 fe40 0000 0101 080a e5cd 7708 ...V.@........w. 0x0030: e5cd 7708 3016 000a 746f 7069 632f 7465 ..w.0...topic/te 0x0040: 7374 6865 6c6c 6f57 6f72 6c64 sthelloWorld ``` >>> Client DISCONNECTs from the broker (see byte 0x0034, first nibble is 0xe - message size is seen at byte 0x0035 : 0x00 = 0 bytes) >>> TCP finishes the connection (flag F) ``` 12:02:58.671518 IP localhost.59258 > localhost.1883: Flags [FP.], seq 59:61, ack 5, win 342, options [nop,nop,TS val 3855447816 ecr 3855447816], length 2 0x0000: 4500 0036 9fc9 4000 4006 9cf6 7f00 0001 E..6..@.@....... 0x0010: 7f00 0001 e77a 075b c312 e8fe 3ab0 a77c .....z.[....:..| 0x0020: 8019 0156 fe2a 0000 0101 080a e5cd 7708 ...V.*........w. 0x0030: e5cd 7708 e000 ..w... ``` ### 3.3. PUBLISHING to the clients (Message from broker to subscribers) >>> Broker PUBLISHes the message "helloWorld" to CLIENT 1 (see byte 0x0034, first nibble is 3 - message size is seen at byte 0x0035 : 0x16 = 22 bytes) ``` 12:02:58.671572 IP localhost.1883 > localhost.55098: Flags [P.], seq 27:51, ack 26, win 342, options [nop,nop,TS val 3855447816 ecr 3855422743], length 24 0x0000: 4500 004c ca31 4000 4006 7278 7f00 0001 E..L.1@.@.rx.... 0x0010: 7f00 0001 075b d73a e527 b639 896a 25b5 .....[.:.'.9.j%. 0x0020: 8018 0156 fe40 0000 0101 080a e5cd 7708 ...V.@........w. 0x0030: e5cd 1517 3016 000a 746f 7069 632f 7465 ....0...topic/te 0x0040: 7374 6865 6c6c 6f57 6f72 6c64 sthelloWorld ``` >>> TCP ack from client 1 to broker ``` 12:02:58.671585 IP localhost.55098 > localhost.1883: Flags [.], ack 51, win 342, options [nop,nop,TS val 3855447816 ecr 3855447816], length 0 0x0000: 4500 0034 58cf 4000 4006 e3f2 7f00 0001 E..4X.@.@....... 0x0010: 7f00 0001 d73a 075b 896a 25b5 e527 b651 .....:.[.j%..'.Q 0x0020: 8010 0156 fe28 0000 0101 080a e5cd 7708 ...V.(........w. 0x0030: e5cd 7708 ..w. ``` >>> Broker PUBLISHes the message "helloWorld" to CLIENT 2 (see byte 0x0034, first nibble is 3 - message size is seen at byte 0x0035 : 0x16 = 22 bytes) ``` 12:02:58.671600 IP localhost.1883 > localhost.59238: Flags [P.], seq 27:51, ack 26, win 342, options [nop,nop,TS val 3855447816 ecr 3855426382], length 24 0x0000: 4500 004c bdbd 4000 4006 7eec 7f00 0001 E..L..@.@.~..... 0x0010: 7f00 0001 075b e766 d255 8044 f2df 0634 .....[.f.U.D...4 0x0020: 8018 0156 fe40 0000 0101 080a e5cd 7708 ...V.@........w. 0x0030: e5cd 234e 3016 000a 746f 7069 632f 7465 ..#N0...topic/te 0x0040: 7374 6865 6c6c 6f57 6f72 6c64 sthelloWorld ``` >>> TCP ack from client 2 to broker ``` 12:02:58.671607 IP localhost.59238 > localhost.1883: Flags [.], ack 51, win 342, options [nop,nop,TS val 3855447816 ecr 3855447816], length 0 0x0000: 4500 0034 388a 4000 4006 0438 7f00 0001 E..48.@.@..8.... 0x0010: 7f00 0001 e766 075b f2df 0634 d255 805c .....f.[...4.U.\ 0x0020: 8010 0156 fe28 0000 0101 080a e5cd 7708 ...V.(........w. 0x0030: e5cd 7708 ..w. ``` >>> TCP ack from broker to client 2 ``` 12:02:58.671620 IP localhost.1883 > localhost.59258: Flags [.], ack 62, win 342, options [nop,nop,TS val 3855447816 ecr 3855447816], length 0 0x0000: 4500 0034 d081 4000 4006 6c40 7f00 0001 E..4..@.@.l@.... 0x0010: 7f00 0001 075b e77a 3ab0 a77c c312 e901 .....[.z:..|.... 0x0020: 8010 0156 fe28 0000 0101 080a e5cd 7708 ...V.(........w. 0x0030: e5cd 7708 ..w. ``` ### REFERENCES [MQTT 3.1.1](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.pdf) ### FUTURE UPGRADES TO THIS PUBLICATION [MQTT 5.0](https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.pdf)