Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subscription could be lost if loop is started before connecting to server. (inconsistiency in docs) #835

Open
5 of 7 tasks
pktiuk opened this issue Apr 18, 2024 · 1 comment
Labels
Status: Available No one has claimed responsibility for resolving this issue. Type: Bug

Comments

@pktiuk
Copy link

pktiuk commented Apr 18, 2024

Prerequisites

Note: You may remove this section prior to submitting your report.

A small team of volunteers monitors issues. Please help us to help you by making it simple to understand and, if possible,
replicate your issue. Prior to reporting a bug please:

  • Test the latest release of the library.
  • Search existing issues.
  • Read the relevant documentation.
  • Review your server configuration and logs.
  • Consider testing against a different server (e.g. mqtt.eclipseprojects.io or test.mosquitto.org)
  • If possible, test using another tool (e.g. MQTTX / mosquitto_sub)
    to confirm the issue is specific to this client.
  • If you are unsure if you have found a bug, please consider asking on stackoverflow for a quicker response.

Bug Description

According do docs:

It is acceptable to firstly launch event loop before connecting.

Connect to a remote broker. This is a blocking call that establishes the underlying connection and transmits a CONNECT packet. Note that the connection status will not be updated until a CONNACK is received and processed (this requires a running network loop, see loop_start, loop_forever, loop…).

But according to examples (like client_sub ) the order is opposite.

mqttc.on_subscribe = on_subscribe
# Uncomment to enable debug messages
# mqttc.on_log = on_log
mqttc.connect("mqtt.eclipseprojects.io", 1883, 60)
mqttc.subscribe("$SYS/#")

When I tried to start loop before connecting I had problems with connection and with subscription.

Reproduction

  1. Run simple MQTT broker
docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083  emqx:5.0.20
  1. Run code
import time
import paho.mqtt.client as mqtt

def on_connect(mqttc, obj, flags, reason_code, properties):
    print("reason_code: " + str(reason_code))

def on_message(mqttc, obj, msg):
    print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))

def on_subscribe(mqttc, obj, mid, reason_code_list, properties):
    print("Subscribed: " + str(mid) + " " + str(reason_code_list))

mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_subscribe = on_subscribe
mqttc.loop_start() ### LOOP STARTED BEFORE CONNECTION
mqttc.connect("localhost", 1883, 60)
print("Is connected: ", mqttc.is_connected())
mqttc.subscribe("/#")

while True:
    time.sleep(1)
  1. Send something to on thread /logs using tool like MQTTX
  2. Subscription does not work (messages are not printed)
$ python3 ./example.py 
Is connected:  False
reason_code: Success

Replacing order in this code

mqttc.connect("localhost", 1883, 60)
mqttc.loop_start() ### LOOP STARTED AFTER CONNECTION

Fixes the issue:

$ python3 ./example.py 
Is connected:  False
reason_code: Success
Subscribed: 1 [ReasonCode(Suback, 'Granted QoS 0')]
/logs 0 b'{\n  "msg": "xxxxxxxxx"\n}'

Environment

  • Python version: 3.10
  • Library version: 2.0
  • Operating system (including version): Ubuntu 22.04
  • MQTT server (name, version, configuration, hosting details): (check repro)

Logs

@github-actions github-actions bot added the Status: Available No one has claimed responsibility for resolving this issue. label Apr 18, 2024
@PierreF PierreF changed the title Loop could not be started before connecting to server. (inconsistiency in docs) Subscription could be lost if loop is started before connecting to server. (inconsistiency in docs) Apr 29, 2024
@PierreF
Copy link
Contributor

PierreF commented Apr 29, 2024

I reproduce your issue and this should either be fixed in code (preferred) or documented.

I've updated the title, since starting the loop before work and the connection works (cf your reason_code: Success message) but the subscribe() is indeed lost. You should be able to see that subscribe() is lost because it return an error (but no example show error checking).

Regardless of this bug, it might be preferable to subscribe in the on_connect callback to be sure your subscription is kept in case of reconnection (I'm not sure the broker had to persist them, especially when clean_session is True - the default). e.g.

def on_connect(mqttc, obj, flags, reason_code, properties):
    print("reason_code: " + str(reason_code))
    mqttc.subscribe("/#")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Available No one has claimed responsibility for resolving this issue. Type: Bug
Projects
None yet
Development

No branches or pull requests

3 participants