IoT Core MQTT msg sending frequency difference between QoS0 and QoS1

0

Hello, I modified the sample program basicPubSub of aws-iot-device-sdk-python and try to send mqtt msg to Iot Core at 10Hz. Also I use AWS MQTT test client to subscribe and monitor the mqtt msg.
I didn't change the AWSIoTMQTTClient connection configuration and only change the QoS by the function myAWSIoTMQTTClient.publish(topic, messageJson, _qos). For _qoS=0, the sending loop time is about 0.1s and MQTT test client update the msg at about 10Hz. However, for _qos=1, the sending loop time become about 0.4~0.7s and MQTT test client update the msg at about 2Hz.

I wonder how to improve the QoS1 sending rate and what is the max frequency for it. Many thanks.

Below is my code for the main loop.

if args.mode == 'both' or args.mode == 'publish':
    message = {}
    message['message'] = args.message
    message['sequence'] = loopCount
    messageJson = json.dumps(message)
    myAWSIoTMQTTClient.publish(topic, messageJson, _qos)
    # if args.mode == 'publish':
    # print('Published topic %s: %s\n' % (topic, messageJson))
    loopCount += 1
toc = time.time()
t_interval = toc -tic
tic = toc
print('[%f]Published topic %s: %s\n' % (t_interval,topic, messageJson))
time.sleep(0.1)
asked 2 years ago472 views
1 Answer
1
Accepted Answer

Hi. In your current code, your QoS sending loop time is almost entirely governed by your time.sleep(0.1) call.

That sample is using the publish() method and it's a blocking call for QoS 1. It will wait for the PUBACK from AWS IoT Core before the call returns: https://github.com/aws/aws-iot-device-sdk-python/blob/0b195b82349e2d5b9715d4880da747bfbaaa1437/AWSIoTPythonSDK/core/protocol/mqtt_core.py#L267-L273

You would likely instead prefer the publishAsync() method. This will not block, and instead allow you to have multiple QoS 1 transactions in flight at once. Please see this sample: https://github.com/aws/aws-iot-device-sdk-python/blob/master/samples/basicPubSub/basicPubSubAsync.py

If you aren't already, you should use the AWS IoT Core endpoint that is in the nearest region, to minimize the round trip time. And if you really want to maximize the throughput, you should remove the time.sleep() altogether.

Note that IoT Core has a limit of 100 publishes per second per client connection. And a maximum of 100 inbound QoS 1 transactions can be in flight at any one time. https://docs.aws.amazon.com/general/latest/gr/iot-core.html#message-broker-limits

Finally I would recommend you instead use the V2 SDK: https://github.com/aws/aws-iot-device-sdk-python-v2. From the V1 README:

A new AWS IoT Device SDK is now available. It is a complete rework, built to improve reliability, performance, and security. We invite your feedback!

This SDK will no longer receive feature updates, but will receive security updates.

profile pictureAWS
EXPERT
Greg_B
answered 2 years ago
  • Thank you for your reply. I haven't tried V2 SDK yet but publishAsync() solved the problem. Really appreicate it!.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions