MQTT Essentials Part 4: MQTT Publish, Subscribe & Unsubscribe

MQTT Essentials Part 4 Banner

Welcome to the fourth part of MQTT Essentials. A ten-part blog series on the core features and concepts of the MQTT protocol. In this post, we focus on publish, subscribe, and unsubscribe in MQTT. Earlier in this series, we covered the basics of the publish/subscribe model. In this post we delve into the specifics of publish/subscribe in the MQTT protocol. If you haven’t read about the basics of the publish/subscribe pattern yet, we strongly encourage you to read that post first.

Last week, we looked at establishing a connection between the MQTT client and broker. This week, we’ll build on that information as we talk about sending and receiving messages.

Publish

An MQTT client can publish messages as soon as it connects to a broker. MQTT utilizes topic-based filtering of the messages on the broker (see (check part 2 for details). Each message must contain a topic that the broker can use to forward the message to interested clients. Typically, each message has a payload which contains the data to transmit in byte format. MQTT is data-agnostic. The use case of the client determines how the payload is structured. The sending client (publisher) decides whether it wants to send binary data, text data, or even full-fledged XML or JSON.

A PUBLISH message in MQTT has several attributes that we want to discuss in detail:

MQTT Publish attributes

Topic Name
The topic name is a simple string that is hierarchically structured with forward slashes as delimiters. For example, “myhome/livingroom/temperature” or “Germany/Munich/Octoberfest/people”. For details on topics, see part 5 of MQTT Essentials.

QoS
This number indicates the Quality of Service Level (QoS) of the message. There are three levels: 0,1, and 2. The service level determines what kind of guarantee a message has for reaching the intended recipient (client or broker). For details on QoS, see part 6 of MQTT Essentials.

Retain Flag
This flag defines whether the message is saved by the broker as the last known good value for a specified topic. When a new client subscribes to a topic, they receive the last message that is retained on that topic. For details on retained messages, see part 8 of MQTT Essentials.

Payload
This is the actual content of the message. MQTT is data-agnostic. It is possible to send images, text in any encoding, encrypted data, and virtually every data in binary.

Packet Identifier
The packet identifier uniquely identifies a message as it flows between the client and broker. The packet identifier is only relevant for QoS levels greater than zero. The client library and/or the broker is responsible for setting this internal MQTT identifier.

DUP flag
The flag indicates that the message is a duplicate and was resent because the intended recipient (client or broker) did not acknowledge the original message. This is only relevant for QoS greater than 0. Usually, the resend/duplicate mechanism is handled by the MQTT client library or the broker as an implementation detail. For more information, see part 6 of MQTT Essentials.

When a client sends a message to an MQTT broker for publication, the broker reads the message, acknowledges the message (according to the QoS Level), and processes the message. Processing by the broker includes determining which clients have subscribed to the topic and sending the message to them.

MQTT Publish Message Flow

The client that initially publishes the message is only concerned about delivering the PUBLISH message to the broker. Once the broker receives the PUBLISH message, it is the responsibility of the broker to deliver the message to all subscribers. The publishing client does not get any feedback about whether anyone is interested in the published message or how many clients received the message from the broker.

Subscribe

Publishing a message doesn’t make sense if no one ever receives it. In other words, if there are no clients to subscribe to the topics of the messages. To receive messages on topics of interest, the client sends a SUBSCRIBE message to the MQTT broker. This subscribe message is very simple, it contains a unique packet identifier and a list of subscriptions.

MQTT Subscribe attributes

Packet Identifier
The packet identifier uniquely identifies a message as it flows between the client and broker. The client library and/or the broker is responsible for setting this internal MQTT identifier.

List of Subscriptions
A SUBSCRIBE message can contain multiple subscriptions for a client. Each subscription is made up of a topic and a QoS level. The topic in the subscribe message can contain wildcards that make it possible to subscribe to a topic pattern rather than a specific topic. If there are overlapping subscriptions for one client, the broker delivers the message that has the highest QoS level for that topic.

Suback

To confirm each subscription, the broker sends a SUBACK acknowledgement message to the client. This message contains the packet identifier of the original Subscribe message (to clearly identify the message) and a list of return codes.

MQTT SUBACK attributes

Packet Identifier
The packet identifier is a unique identifier used to identify a message. It is the same as in the SUBSCRIBE message.

Return Code
The broker sends one return code for each topic/QoS-pair that it receives in the SUBSCRIBE message. For example, if the SUBSCRIBE message has five subscriptions, the SUBACK message contains five return codes. The return code acknowledges each topic and shows the QoS level that is granted by the broker. If the broker refuses a subscription, the SUBACK message conains a failure return code for that specific topic. For example, if the client has insufficient permission to subscribe to the topic or the topic is malformed.

Return Code Return Code Response
0 Success – Maximum QoS 0
1 Success – Maximum QoS 1
2 Success – Maximum QoS 2
128 Failure

MQTT Subscribe Flow

After a client successfully sends the SUBSCRIBE message and receives the SUBACK message, it gets every published message that matches a topic in the subscriptions that the SUBSCRIBE message contained.

Unsubscribe

The counterpart of the SUBSCRIBE message is the UNSUBSCRIBE message. This message deletes existing subscriptions of a client on the broker. The UNSUBSCRIBE message is similar to the SUBSCRIBE message and has a packet identifier and a list of topics.

MQTT Unsubscribe attributes

Packet Identifier
The packet identifier uniquely identifies a message as it flows between the client and broker. The client library and/or the broker is responsible for setting this internal MQTT identifier.

List of Topic
The list of topics can contain multiple topics from which the client wants to unsubscribe. It is only necessary to send the topic (without QoS). The broker unsubscribes the topic, regardless of the QoS level with which it was originally subscribed.

Unsuback

To confirm the unsubscribe, the broker sends an UNSUBACK acknowledgement message to the client. This message contains only the packet identifier of the original UNSUBSCRIBE message (to clearly identify the message).

MQTT UNSUBACK attributes

Packet Identifier
The packet identifier uniquely identifies the message. As already mentioned, this is the same packet identifier that is in the UNSUBSCRIBE message.

Unsubscribe Flow

After receiving the UNSUBACK from the broker, the client can assume that the subscriptions in the UNSUBSCRIBE message are deleted.


That’s the end of part four in our MQTT Essentials series. We hope you enjoyed it. In our next post, we dig deeper into how MQTT topics are used. We’ll cover topic basics, how to use wildcards, and provide plenty of practical examples.

Have a great week and we hope to see you on the next MQTT Monday!

If you still haven’t signed up for our newsletter, enter your email in the subscription form below to get posts as soon as they are published. If you prefer RSS, you can subscribe to our RSS feed here.

48 comments

  1. Guy Avraham says:

    Hi there,

    Correct me if I’m mistaken , but in the example of the SUBSCRIBE/SUBACK messages , isn’t the packetId filed should be the same (therefor , in the SUBACK message , it should be modified to the value of the corresponding SUBSCRIBE message , which is 4312) ?

    Other than that , these tutorials are great !!
    Great work guys !!

    Thanks,
    Guy.

    1. Hi Guy,

      thanks so much for the feedback. Your are right, it seems there is indeed an error in the picture. Nice catch! 🙂

      All the best,
      Dominik from the HiveMQ Team

  2. Nena says:

    Is it bad practice to send an unsolicited message to an MQTT client? Ie, the client has not subscribed to a particular topic, but the broker sends a message to the client anyways? Example, in the event of an error?

    1. Hi Nena,

      it is possible with HiveMQ’s plugin system to do this, but it is bad practice since the client might not expect to receive a message on a topic it is not subscribed to.

      Hope that helps,
      Christoph from the HiveMQ Team

  3. triawan says:

    hi, what is the meaning of this “received PUBLISH (d0, q0, r0, m0, ‘get/123’, … (70 bytes))” ?

    1. Hi triawan,

      the fields have the following meaning:
      d0 => duplicate flag: false
      q0 => QoS: 0
      r0 => retained: false
      m0 => messageID: 0

      Hope that helps,
      Christoph from the HiveMQ Team

    2. sanlie says:

      it trace string for :
      dup flag = false, qos = 0 (atMostOnce), retained = false, mesageId = 0, topic: ‘get/123’, 70 bytes: packet length from PUBLISH message

  4. Phuoc Thua says:

    Hi,

    I have tried to assign a struct into payload (using Paho client, convert to void* before assigning). I published success, the subscriber can received it. But when I converted the payload from void* to struct to use I got segmentaion fault (core dumped). So can the payload only point to a char array (or it can only be “the actual content of the message” as the article) ?

    Thanks,
    Phuoc Thua.

    1. Charles says:

      Hi Phuoc,

      You probably need to serialize your structure into a sequential byte array, and then send that as message payload.
      On the receiving end, you need to deserialize the byte array into your structure.

      Hope this helps,
      Charles

  5. Kamala Kris says:

    In SUBSCRIBE example figure the topic 2 should be topic/2 and not topic/1. Correct me if I am wrong.

    1. Hi Kamala,

      good catch! The topic2 should indeed be “topic/2”.

      Thanks and all the best,
      Dominik from the HiveMQ Team

  6. Sudeep Nayak says:

    Hi,

    I’m working on sharing images and videos using Mqtt. I want to know if the total transfer time depends on the number of clients receiving the file? And also, which encoding scheme works fastest to transfer images/video?

    Thanks.

    1. Hi Sudeep,

      I’m not sure what you mean with total transfer time. I’m assuming you mean end-to-end latency. You can check out the benchmarks here for some numbers: http://www.hivemq.com/benchmarks/

      Best,
      Dominik from the HiveMQ Team

  7. Chase says:

    First, thanks for this really fantastic series. I have a small (maybe picky) but I think important suggestion.

    Under the “DUP flag” subheading you state:

    “So when a client sends a publish to a MQTT broker…”

    It’s my understanding that clients don’t publish anything TO the broker but instead just publish. Although this seems nit-picky, as a complete MQTT beginner, it is a point of confusion for me. I think correctly understanding the structure of the MQTT ecosystem is absolutely essential before diving into understanding how to use it. The fact that clients are just publishing, and that it’s the broker that controls “grabbing” (subscribing) to the data that is flying around… is a really important thing to understand correctly.

    Now, if I’m wrong about this point PLEASE correct me, as it will help me, and others, move forward in learning MQTT.

    Thanks again for this series and your dedication to responding to the comments!

    -Chase

    1. Hallo Chase,

      this is a good question. Let me try to clarify as simple as possible.
      if you look into the message flow of a MQTT message from the publisher to the subscriber, the following happens.

      Let’s assume we have ClientA publishing on topic: “anytopic” and we have ClientB subscribing on “anytopic”
      ClientA will publish the message “Some Payload” with the topic to HiveMQ.
      Now HiveMQ will check, which clients have subscriptions on that topic and will publish the message to those clients, in this case ClientB.

      Note that this is a simplified view and many MQTT specific mechanisms like QoS have not been considered.

      I hope this helps.

      Florian, from the HiveMQ Team.

    2. simarjeet singh says:

      Hi,

      I want to know how i can make one client as publisher as well as subscriber?
      i have made publisher and subscriber but subscriber callback is not working until i disconnect client. Means i am not getting duplex communication, either i can publish or only subscribe.

      Please let me the solution for this.
      email id: simarjeet.singh@blackpeppertech.com

    3. Hi Simarjeet,

      MQTT clients aren’t separated in publishers or subscribers. That means that it is possible for each client to be publisher and subsriber at the same time.

      For help with your specific problem we recommend contacting the support of the client library you are using.

      Kind regards,
      Abdullah from The HiveMQ Team.

  8. Axel says:

    Dear HiveMQ Team,

    Thank you very much for this great tutorial! Made my first mqtt steps much easier.

    Please allow me a question: I played with different Clients (also with your web Client) but I had always the effect that when I publish an identical message twice (QOS=0, retain=true) then my subsriber receives two messages. I expected that I receive the first message only. And after that only changes of the message will be received.
    Is my understanding or my configuration of the Publisher wrong.

    Thank you very much in advance.
    Best Regards
    Axel

    1. Hallo Axel,

      Glad to see you like our content and it helped you get started with MQTT.

      Regarding your question:
      Unfortunately your understanding of retained messages is indeed incorrect. One retained message for a specific topic (The last message published on the topic, regardless of the payload) can be stored by the broker so that any new subscribers on that specific topic will be able to get that message. This does not in any way influence the message flow of currently connected subscribers.
      See this post from this series for further information.

      I hope that was helpful.
      Best regards,
      Florian, from the HiveMQ Team.

  9. Ashutosh says:

    Dear HiveMQ Team,

    Thanks for this in-depth knowledge series for MQYY, its really simplistic approach to guide the MQTT basics.

    I am stuck at understanding one sentence from Publish section –
    “The publishing client doesn’t get any feedback, if someone was interested in this published message and how many clients received the message by the broker.”

    My understading is publishing client doesnt get any feedback if someone is NOT interested in published message means no one has subscribed to that topic. Is it correct?

    Also didnt get context of – how many clients received the message by the broker.

    Will you please put some more light on it?

    Thanks,

    Ashutosh

    1. Hallo Ashutosh,

      Thank you for the kind words.
      I believe you’re understanding is already correct. What is meant by this sentence is very simple.
      The publisher doesn’t get any feedback about the subscribers, nor does he get feedback, when any of the subscribers actually receive the message.

      I hope this clarifies things. Let me know if you have a follow up question.
      Kind regards,
      Florian, from The HiveMQ Team.

  10. Susanna says:

    Dear HiveMQ Team,
    thanks for the great work on creating these very nice tutorials! as a very beginner with MQTT, I have a (probably trivial) question: is it possible that an MQTT client is at the same time both publisher and subscriber of a topic? If yes, does it mean that the message published by that client on that specific topic gets back to the same client, that is also a subscriber of that topic?
    thanks a lot,
    Susanna

    1. Hallo Susanna,

      Thank you for the kind words, we’re glad to see you are taking an interest in MQTT.
      In short: It is absolutely possible for a client to be both Publisher and Subscriber. As long as you do not subscribe on the topic, you are publishing on, the broker will not send the message back to your client.

      Kind regards,
      Florian from The HiveMQ Team.

  11. Shahzad says:

    Great tutorials!
    The post states **MQTT is data-agnostic and it totally depends on the use case how the payload is structured. It’s completely up to the sender if it wants to send binary data, textual data or even full-fledged XML or JSON**.

    I wonder if MQTT works on binary payload, than how subscribers will know that what type of data they are receiving (may be some one published a JSON, XML or even an image on the same topic). Is there anything like content-type as in HTTP which can tell what type of payload is?
    Thanks a lot.

    1. Hallo Sahzad,

      Glad you like the tutorial. You bring up a good question and almost answered it yourself already.
      The solution is to have dedicated topics for specific content types. A flag like in HTTP does not exist.

      Kind regards,
      Florian

  12. Hiren R Kanetiya says:

    How can i set a multiple Subscribe with different topic in particularly for ios objective C ? Please help me…
    i have set like this :
    [objCocoaMQTT subscribe:@”customToRM” qos:1];
    [objCocoaMQTT subscribe:@”approvedTopic” qos:2];
    IS it correct or not ? How can i check this would be setting the two different topic ? in code and as well as on debug log

    1. Hi there,

      Glad to see you’re taking an interest in MQTT. This blogpost shows the use of the objective C project for IoS.
      For more detailed information on the project please refer to the Github Page

      Kind regards,
      Florian from the HiveMQ Team.

  13. Christopher Maynard says:

    For the description of Packet Identifier under Subscribe, it is mentioned that, “This is only relevant for QoS greater than zero.” Isn’t that only true of the Publish messages? My understanding after reading section 2.3.1, and specifically Table 2.5 of MQTT Version 3.1.1, as well as section 3.8.2, is that the Packet Identifier is required for the Subscribe message, regardless of QoS.

    1. Hi Christopher,

      You are making an excellent point. The packet identifier is relevant for any MQTT message, that needs to be acknowledged.
      So besides PUBLISH greater than zero this is true for any SUBSCRIBE, UNSUBSCRIBE and CONNECT message.
      Thank you for pointing this out, I will adjust the post accordingly.

      Kind regards,
      Florian from the HiveMQ Team.

  14. NuB2Hive says:

    Hi, Wonderful tutorial!

    Q: Can a Client Subscribe to a Topic before any message on that topic has been published? Assume HiveMQ eventually flushed subscriptions like this that time out?

    Thx

    1. Hi there,

      Glad you are taking and interest in MQTT and that you like the tutorial.
      Regarding your question:
      Yes, you can absolutely subscribe to a topic no message has been published on yet.
      Not sure what you are asking on your second question. I will try to answer regardless.
      When taking advantage of the cleanSession=false option for your connection, HiveMQ will store the subscription even after a client times out.
      Otherwise the subscription will be removed, once the client disconnects.
      You can see this post for more information on that.
      Kind regards,
      Florian from the HiveMQ Team.

  15. NuB2Hive says:

    Thanks Florian you answered the second question too.

  16. saikiran says:

    Firstly, thanks for the wonderful information.

    I have a query. Please clarify!
    In case a client has sent an Unsubscribe request to broker. Lets say if some of the topics doesn’t exists at all. So in that case how would what will happen (since UnsubAck doesn’t have specific topics mentioned and just the message id, what will happen?)

    1. Hi there,

      Glad you like the information.
      When you unsubscribe from a topic the broker will acknowledge the UNSUBSCRIBE and remove the subscription for that clientID. If there was no subscription for that clientID on that topic nothing will happen. At the end of an unsubscribe, regardless of there being a subscription on that topic in place or not, the client will no longer be subscribed to the topic.

      I hope this answers your questions.

      Kind regards,
      Florian from The HiveMQ Team.

  17. Mathew says:

    Hi,
    Thank you very much for your tutorial.

    I have a query.

    I am using publish function as follows ‘ Client.Publish(“Queue”, Encoding.UTF8.GetBytes(“datastring”), MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE, true); and subscriber as client.Subscribe(“Queue”, Encoding.UTF8.GetBytes(“datastring”), MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE);
    But the problem is whenever I am calling the subscriber method the last published message is coming.
    how to avoid this, to subscribe message only once

    Regards,
    Mathew

    1. Hi Mathew,

      Great to see you are taking an interest in MQTT and thank you for the kind words.
      Some research on your query on my end suggests, that this code is referring to a Paho Python implementation.
      It looks as if you were taking advantage of the Retained Message feature for your publish.
      This would explain the described behaviour. So changing the last argument in your Client.Publish() method from true to false should resolve this.
      Please bare in mind that you reached out to HiveMQ not Paho – I am not an expert on client implementations.
      I would appreciate you letting me know, wether this resolved the issue for you.
      Kind regards,
      Florian from The HiveMQ Team.

  18. Prabhunath Gupt says:

    Hi,

    This is amazing tutorial to understand MQTT.

    I have subscribed multiple topics using wild card feature and i am getting multiple messages at receiver even if i am publish only one message. These messages contain garbage topic name and data.

    I have used QOS level : 0.

    Please help me to resolve this issue and do let me know if more details are required.

    Regards,
    Prabhunath

    1. Hi Prabhunath,

      Nice to see you are taking an interest in MQTT and HiveMQ and thank you for the kind words.
      Assuming I understand you correctly, this is not the expected behaviour for MQTT.
      Let me demonstrate the way it is supposed to work:
      Client A subscribes to Topic = ‘#’ and Topic = ‘data/+/house’
      Client B publishes a message on Topic = ‘data/north/house’
      Client A will only receive the message once

      This is how HiveMQ works at least. Are you using HiveMQ as your broker?
      Which MQTT Client Library are you using?

      Kind regards,
      Florian, from The HiveMQ Team.

  19. Sai Kiran says:

    Hi,

    Is there any way in MQTT by which I can get to know to which port subscribers(clients) are connected to?
    And also, is it possible to have a video conference using MQTT? If yes, what’s the exact procedure?

    Thanks in advance.

    1. Hi Sai,

      Nice to see you’re taking an interest in MQTT and HiveMQ.
      The HiveMQ Web UI Client Detail View does provide information on the used listener for clients.
      In regards to your video conference question:
      It’s possible to stream video with MQTT in principal. The exact implementation is dependant on the specific use case at hand.
      In case you have a concrete business case in mind you’re welcome to contact sales@hivemq.com and request consulting.

      Kind regards,
      Florian from The HiveMQ Team.

  20. Jens says:

    So I can´t see a way of doing “multi-publish” in mqtt, basically publishing different values to different topics at the same time. Is there a way of avoiding latency + overhead due to sending as many tcp-packages as there are value changes to be pushed?

  21. Akshay M Patil says:

    Hello,
    Below is the data i am receiving on subscriber side on topic “/test” but sometimes i am getting the data from another topic “/devices/…..”. I am running publisher and subscriber on different terminal.what is the problem

    MQTT SUB created….
    MQTT SUB Successfully connected to Server
    MQTT SUBSCRIBE to Server
    Message arrived
    topic: /test
    message is:hello
    Message arrived
    topic: devices/messages/events
    message is:{“GWDATA”:{“MAC”: “”,”TS”: “8”,”GPS”:{“PID”:””,”SN”: “”,”CSQ”: “”PS”: “0”,”BV”: “”,”PT”: “0”,”PV”: “V”,”FX”: “1”,”PDP”: “”,”HDP”: “”,”VDP”: “”,”LAT”: “”,”N/S”: “”,”LON”: “”,”E/W”: “”,”Speed”: “”,”TA”: “”,”DT”: “”,”IGN”}
    Message arrived
    topic: /test
    message is:hello
    Message arrived
    topic: /test
    message is:hello

    1. Hi Akshay,

      Nice to see you’re taking an interest in MQTT.

      Clients can only receive messages from subscribed topics. That means that your client must have subscribed to that topic in a previous connection. You must know that with cleanSession=false the broker stores the subscriptions over multiple connections.

      For more information about sessions read also MQTT Essentials Part 7: https://www.hivemq.com/blog/mqtt-essentials-part-7-persistent-session-queuing-messages.

      Kind regards,
      Abdullah from The HiveMQ Team.

  22. Sakthivel says:

    I have question on MQTT QoS level 1.

    What is behaviour when subscriber client has qos 1 and publisher client publish the data with qos0.
    Does MQTT Broker will publish data to subscriber client with qos1 or qos 0 ?

    I didn’t get clear idea from specification, could please explain HiveMQ Broker behaviour on this and what spec says ?

    1. Hi Sakthivel,

      nice to see you’re taking an interest in MQTT and HiveMQ.

      In such a case will be the QoS level of the message used.
      That means that the subscriber will receive the message with QoS 0.

      Kind regards,
      Abdullah from the HiveMQ Team.

  23. Forgaoqiang says:

    This is really great torturial , thanks for post it, i have same questions ~
    What will happen if there is no subscriber for a topic? Will the topic be deleted?
    Is topic been created when a client subscribe or publish a msg into it?
    I still do not really understand the retain flag , if there are two publisher send different retain msg to the same topic, the last msg will overlay the previous one ?
    Thansk once more

    1. Hello Forgaoqiang,

      Thank you for the kind words. It’s great to see you’re having an interest in MQTT and HiveMQ and you are liking our content.
      Topic in MQTT are completely dynamic, meaning they will be created as a publish is received and a subscription exists for the topic.
      If a publish arrived for a topic that no subscribers exist for the message will be dropped. Your understanding of retained messages is correct.

      I hope this helps.
      Kind regards,
      Florian from the HiveMQ Team.

Leave a Reply

Your email address will not be published. Required fields are marked *