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

Consistent MMQTTException: Connection Refused - Unauthorized after 2-2.5 hours uptime #53

Open
BlitzCityDIY opened this issue Jul 15, 2022 · 10 comments

Comments

@BlitzCityDIY
Copy link
Contributor

BlitzCityDIY commented Jul 15, 2022

Hello,

Recently I've noticed an issue where after approximately 2-2.5 hours of uptime, a KeepAlive period elapses and the code can't get a PINGRESP from the server and errors out:

7566.375: DEBUG - KeepAlive period elapsed - requesting a PINGRESP from the server...
7566.377: DEBUG - Sending PINGREQConnection error, reconnecting
PINGRESP not returned from broker.
7690.494: INFO - - iot_mqtt :: reconnect ::
7690.496: DEBUG - Attempting to reconnect with MQTT broker
7690.498: DEBUG - Attempting to establish MQTT connection...
7690.502: INFO - Establishing a SECURE SSL connection to iotc-----.azure-devices.net:8883
7691.429: DEBUG - Sending CONNECT to broker...
7691.434: DEBUG - Fixed Header: bytearray(b'\x10\xa7\x02\x00') Variable Header: bytearray(b'\x04MQTT\x04\xc2\x00x')
7691.445: DEBUG - Receiving CONNACK packet from broker
Traceback (most recent call last):
File "code.py", line 232, in
File "adafruit_azureiot/iotcentral_device.py", line 193, in reconnect
File "adafruit_azureiot/iot_mqtt.py", line 439, in reconnect
File "adafruit_minimqtt/adafruit_minimqtt.py", line 770, in reconnect
File "adafruit_minimqtt/adafruit_minimqtt.py", line 523, in connect
MMQTTException: Connection Refused - Unauthorized

There is a try and except in the loop:

except (ValueError, RuntimeError) as e:
        print("Connection error, reconnecting\n", str(e))
        wifi.radio.enabled = False
        wifi.radio.enabled = True
        wifi.radio.connect(secrets["ssid"], secrets["password"])
        device.reconnect()
        continue

But it doesn't seem to trigger a reconnection. Have tried with CP 7.3 and CP 8 on an ESP32-S2 Feather TFT and a QT Py ESP32-S2 both with my own project code and the example library code for IoT Central.

@brentru
Copy link
Member

brentru commented Jul 15, 2022

@jimbobbennett This seems to be an issue where the PING/PINGRESP packet is dropped. I am unsure if it's at Azure's end, or CircuitPython. Could you possibly shed some light on what's happening for @BlitzCityDIY ?

@jimbobbennett
Copy link
Collaborator

Can you confirm how long till the connection drops? The token that is generated is valid for 6 hours by default, and after that you will need to re-generate the device client object to get a new valid token. You can also change this by setting a longer expiry when creating the device client.

@BlitzCityDIY
Copy link
Contributor Author

hi @jimbobbennett - it was consistently dropping around the 2 hour mark.

@jimbobbennett
Copy link
Collaborator

Weird. What time zone are you in? If you are 4 hours from UTC then maybe something has gone wrong with how it computes the expiry time, so the 6 hours becomes 2 hours plus a UTC offset of 4 hours.

@BlitzCityDIY
Copy link
Contributor Author

Oh interesting! I am -4 UTC. I'll try running it without the offset to see if the same issue occurs.

@jimbobbennett
Copy link
Collaborator

Hopefully this is the issue! I guess we need better documentation around expiry and how to reconnect though.

@BlitzCityDIY
Copy link
Contributor Author

So I changed the tz_offset to 0 from -4 and it did stay up for 6 hours. However, it did not reconnect and threw the same MQTTException

Traceback (most recent call last):
File "code.py", line 232, in
File "adafruit_azureiot/iotcentral_device.py", line 193, in reconnect
File "adafruit_azureiot/iot_mqtt.py", line 439, in reconnect
File "adafruit_minimqtt/adafruit_minimqtt.py", line 770, in reconnect
File "adafruit_minimqtt/adafruit_minimqtt.py", line 523, in connect
MMQTTException: Connection Refused - Unauthorized

This is the except portion of the code. I added OSError and broad Exception to try and catch the MQTTException:

except (ValueError, RuntimeError, OSError, Exception) as e:
        print("Connection error, reconnecting\n", str(e))
        wifi.radio.enabled = False
        wifi.radio.enabled = True
        wifi.radio.connect(secrets["ssid"], secrets["password"])
        device.reconnect()
        continue

@jimbobbennett
Copy link
Collaborator

reconnect doesn't create a new SAS token with an updated expiry, you will need to create a whole new device connection object. Maybe something to be improved in the API.

@BlitzCityDIY
Copy link
Contributor Author

Oh I see. To generate a new SAS token then, should we be having folks reload code.py? Or is there a better method you'd suggest?

@jimbobbennett
Copy link
Collaborator

Recreate the device object - its in the construction of that object that the SAS token is create.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants