mehdi alizade
mehdi alizade

Reputation: 67

Feedback message from subscriber in mqtt protocol

I used the MQTT protocol to send messages between two computers. I have patterned from this code. publisher:

import paho.mqtt.client as mqtt
from random import randrange, uniform
import time

mqttBroker ="mqtt.eclipse.org" 

client = mqtt.Client("Temperature_Inside")
client.connect(mqttBroker) 

while True:
    randNumber = randrange(10)

    client.publish("TEMPERATURE", randNumber)
    print("Just published " + str(randNumber) + " to topic TEMPERATURE")
    time.sleep(1)

subscriber:

import paho.mqtt.client as mqtt
import time

def on_message(client, userdata, message):
    print("received message: " ,str(message.payload.decode("utf-8")))

mqttBroker ="mqtt.eclipse.org"

client = mqtt.Client("Smartphone")
client.connect(mqttBroker) 

client.loop_start()

client.subscribe("TEMPERATURE")
client.on_message=on_message 

time.sleep(1)
client.loop_stop()

I want a feedback to be sent to the publisher when I receive the message. Is there a way to get message feedback?

Upvotes: 1

Views: 609

Answers (2)

Nick Hyland
Nick Hyland

Reputation: 357

To ensure your message will get delivered you can use QoS. This can be set when publishing or subscribing. So for your case you will want either QoS 1 or 2. QoS 2 ensures it will reach the broker exactly once when publishing, and if subscribed at QoS 2 it will ensure the subscriber gets the message exactly once. Note though QoS 2 is the slowest form of publishing and subscribing. I find the most common way to deal with messages is with QoS 1, and then in your subscribe on_message you can determine how to deal with duplicate messages yourself. The paho mqtt client allows you to set QoS when publishing or subscribing but it defaults to 0. I've updated your code below.

# publisher
import paho.mqtt.client as mqtt
from random import randrange, uniform
import time
import json

mqttBroker ="mqtt.eclipse.org" 

client = mqtt.Client("Temperature_Inside")
client.connect(mqttBroker) 

id = 1
while True:
    randNumber = randrange(10)
    message_dict = { 'id': id, 'value': randNumber }

    client.publish("TEMPERATURE", json.dumps(message_dict), 1)
    print("Just published " + str(randNumber) + " to topic TEMPERATURE")
    id += 1
    time.sleep(1)

# subscriber
import paho.mqtt.client as mqtt
import time
import json
from datetime import datetime

parsed_messages = {}

def on_message(client, userdata, message):
    json_body = json.loads(str(message.payload.decode("utf-8")))
    msg_id = json_body['id']
    if msg_id in parsed_messages.keys
        print("Message already recieved at: ", parsed_messages[msg_id].strftime("%H:%M:%S"))
    else
        print("received message: " ,json_body['value'])
        parsed_messages[msg_key] = datetime.now()
    

mqttBroker ="mqtt.eclipse.org"

client = mqtt.Client("Smartphone")
client.connect(mqttBroker) 

client.loop_start()

client.subscribe("TEMPERATURE", 1)
client.on_message=on_message 

time.sleep(1)
client.loop_stop()

Note it is important that the subscriber also defines QoS 1 on subscribing otherwise it will subscribe with QoS 0 which is default for the paho client, and the message will get downgraded to 0, meaning the message will get delivered at most once (but may not get delivered at all if packet dropped). As stated the above only ensures that the message will get received by the subscriber. If you want the publisher to get notified when the subscriber has processed the message you will need to publish on a new topic (with some uuid) when the subscriber has finished processing that the publisher can subscribe to. However when I see this being done I often question why use MQTT, and not just send HTTP requests. Here is a good link on MQTT QoS if you're interested (although it lacks detail on what happens from subscriber side).

Upvotes: 0

hardillb
hardillb

Reputation: 59608

There is no end to end delivery notification in the MQTT protocol. This is very deliberate.

MQTT is a pub/sub system, designed to totally separate the producer of information from the consumer. There could be 0 to infinite number of subscribers to a topic when a producer publishes a message. There could also be offline subscribers who will have the message delivered when they reconnect (which could be any time after the message was published)

What MQTT does provide is the QOS levels, but it is important to remember that these only apply to a single leg of the delivery journey. E.g. a message published at QOS 2 ensures it will reach the broker, but makes no guarantees about any subscribers as their subscription may be at QOS 0.

If your system requires end to end delivery notification then you will need to implement a response message yourself, this is normally dinner by including a unique ID in the initial message and sending a separate response message in a different topic also containing that ID

Upvotes: 1

Related Questions