adafruit / Adafruit_CircuitPython_MiniMQTT

MQTT Client Library for CircuitPython
Other
80 stars 51 forks source link

MQTT Connection Breaks After Reconnecting to WiFi When Messages Are Sent During Disconnection #222

Closed ilshm closed 2 months ago

ilshm commented 2 months ago

I'm using a Raspberry Pi Pico W with an MQTT client to connect to Adafruit IO. The Pico W handles WiFi reconnection well when the connection drops. However, there's an issue when messages are sent to the subscribed topic while the Pico W is disconnected from WiFi. After reconnecting to WiFi:

  1. The Pico W does not receive new messages that are sent after it reconnects.
  2. After a few seconds, it becomes unstable and eventually fails to reconnect to the MQTT broker entirely.
  3. The log shows a socket error: "An existing socket is already connected to mqtt://io.adafruit.com:1883".

Important Note: If no messages are sent to the topic while the Pico W is offline, everything works as expected. The Pico W maintains the same MQTT connection after WiFi reconnection and continues receiving messages without any issues. In this case, the Pico doesn’t even need to reconnect to the broker—everything remains stable and functional.

Steps to Reproduce:

  1. Connect the Pico W to WiFi and the MQTT broker.
  2. Subscribe to a topic (e.g., myfeed/onoff).
  3. Disconnect the Pico W from WiFi (e.g., by disabling the hotspot).
  4. While the Pico W is disconnected, send a message to the topic (e.g., using Adafruit IO).
  5. Re-enable WiFi, allowing the Pico W to reconnect automatically.
  6. Observe that the Pico W fails to handle incoming messages and eventually cannot reconnect to the MQTT broker.

Log Output:

Connecting to WiFi
Connected to WiFi
My MAC addr: ['0x28', '0xcd', '0xc1', '0x3', '0xeb', '0x27']
My IP address is 192.168.169.203
...
KeepAlive period elapsed - requesting a PINGRESP from the server...
Sending PINGREQ
Attempting to reconnect with MQTT broker
Resetting reconnect backoff
Attempting to connect to MQTT broker (attempt #0)
Attempting to establish MQTT connection...
Socket error when connecting: An existing socket is already connected to mqtt://io.adafruit.com:1883

The problem seems tied to messages being sent to the topic while the Pico W is disconnected from WiFi.

justmobilize commented 2 months ago

So if you do the same thing, but skip step 4, it connects fine?

ilshm commented 2 months ago

So if you do the same thing, but skip step 4, it connects fine?

True

justmobilize commented 2 months ago

Are you calling MQTT.reconnect()?

ilshm commented 2 months ago

Are you calling MQTT.reconnect()?

Yes, if I don't call it everything is the same, after WiFi reset - works, if during the outage no messages arrive.

justmobilize commented 2 months ago

So that's probably the issue, since the socket was never flagged as disconnected. Can you try something for me? before you call reconnect(), can you call _close_socket()? This should fully disconnect the socket so it can be reused

justmobilize commented 2 months ago

Wanted to follow-up and see if that fixed it. If so we can figure out the right way to do this

ilshm commented 2 months ago

Sorry for the delayed response. After experimenting with it, I found that the solution is either to call _close_socket() manually or to modify the reconnect() function to include this call. Thanks!