Skip to content

Commit 512086b

Browse files
committed
fix: prevent MQTT disconnect loop by reusing Paho client on reconnect
mqttStart() called MQTTAsync_create()/MQTTClient_create() on every invocation, including reconnects from mqttEvery5Seconds(). This leaked the old Paho client handle without destroying it. The old client's internal threads would eventually reconnect using the same MQTT clientID, causing the broker to disconnect the new client ("session taken over"), creating a permanent connect/disconnect loop. Fix: create the Paho client once (guarded by mqttClientCreated flag) and reuse it on reconnect, matching the ESP32 implementation pattern. Properly destroy the client in mqttStop(). Affects: hasp_mqtt_paho_async.cpp (Linux, macOS, Windows async builds) hasp_mqtt_paho_single.cpp (Windows synchronous builds) Does not affect: ESP32/ESP8266/STM32 (different MQTT implementations) Fixes #1005 Made-with: Cursor
1 parent c387627 commit 512086b

2 files changed

Lines changed: 38 additions & 22 deletions

File tree

src/mqtt/hasp_mqtt_paho_async.cpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ uint16_t mqttPort = MQTT_PORT;
8383

8484
MQTTAsync mqtt_client;
8585

86+
static bool mqttClientCreated = false;
8687
static bool mqttConnecting = false;
8788
static bool mqttConnected = false;
8889

@@ -361,18 +362,21 @@ void mqttStart()
361362
int rc;
362363
int ch;
363364

364-
if((rc = MQTTAsync_create(&mqtt_client, mqttServer.c_str(), haspDevice.get_hostname(), MQTTCLIENT_PERSISTENCE_NONE,
365-
NULL)) != MQTTASYNC_SUCCESS) {
366-
LOG_ERROR(TAG_MQTT, "Failed to create client, return code %d", rc);
367-
rc = EXIT_FAILURE;
368-
return;
369-
}
365+
if(!mqttClientCreated) {
366+
if((rc = MQTTAsync_create(&mqtt_client, mqttServer.c_str(), haspDevice.get_hostname(), MQTTCLIENT_PERSISTENCE_NONE,
367+
NULL)) != MQTTASYNC_SUCCESS) {
368+
LOG_ERROR(TAG_MQTT, "Failed to create client, return code %d", rc);
369+
rc = EXIT_FAILURE;
370+
return;
371+
}
370372

371-
if((rc = MQTTAsync_setCallbacks(mqtt_client, mqtt_client, connlost, mqtt_message_arrived, NULL)) !=
372-
MQTTASYNC_SUCCESS) {
373-
LOG_ERROR(TAG_MQTT, "Failed to set callbacks, return code %d", rc);
374-
rc = EXIT_FAILURE;
375-
return;
373+
if((rc = MQTTAsync_setCallbacks(mqtt_client, mqtt_client, connlost, mqtt_message_arrived, NULL)) !=
374+
MQTTASYNC_SUCCESS) {
375+
LOG_ERROR(TAG_MQTT, "Failed to set callbacks, return code %d", rc);
376+
rc = EXIT_FAILURE;
377+
return;
378+
}
379+
mqttClientCreated = true;
376380
}
377381

378382
mqttEnabled = mqttServer.length() > 0 && mqttPort > 0;
@@ -410,6 +414,8 @@ void mqttStart()
410414

411415
void mqttStop()
412416
{
417+
if(!mqttClientCreated) return;
418+
413419
int rc;
414420
MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer;
415421
disc_opts.onSuccess = onDisconnect;
@@ -418,6 +424,8 @@ void mqttStop()
418424
LOG_ERROR(TAG_MQTT, "Failed to disconnect, return code %d", rc);
419425
rc = EXIT_FAILURE;
420426
}
427+
MQTTAsync_destroy(&mqtt_client);
428+
mqttClientCreated = false;
421429
}
422430

423431
void mqttSetup()

src/mqtt/hasp_mqtt_paho_single.cpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ uint16_t mqttPort = MQTT_PORT;
8080

8181
MQTTClient mqtt_client;
8282

83+
static bool mqttClientCreated = false;
8384
int disc_finished = 0;
8485
int subscribed = 0;
8586
int connected = 0;
@@ -300,18 +301,21 @@ void mqttStart()
300301
int ch;
301302

302303
LOG_DEBUG(TAG_MQTT, "%s %d", __FILE__, __LINE__);
303-
if((rc = MQTTClient_create(&mqtt_client, mqttServer.c_str(), haspDevice.get_hostname(), MQTTCLIENT_PERSISTENCE_NONE,
304-
NULL)) != MQTTCLIENT_SUCCESS) {
305-
LOG_ERROR(TAG_MQTT, "Failed to create client, return code %d", rc);
306-
rc = EXIT_FAILURE;
307-
return;
308-
}
304+
if(!mqttClientCreated) {
305+
if((rc = MQTTClient_create(&mqtt_client, mqttServer.c_str(), haspDevice.get_hostname(), MQTTCLIENT_PERSISTENCE_NONE,
306+
NULL)) != MQTTCLIENT_SUCCESS) {
307+
LOG_ERROR(TAG_MQTT, "Failed to create client, return code %d", rc);
308+
rc = EXIT_FAILURE;
309+
return;
310+
}
309311

310-
if((rc = MQTTClient_setCallbacks(mqtt_client, mqtt_client, connlost, mqtt_message_arrived, NULL)) !=
311-
MQTTCLIENT_SUCCESS) {
312-
LOG_ERROR(TAG_MQTT, "Failed to set callbacks, return code %d", rc);
313-
rc = EXIT_FAILURE;
314-
return;
312+
if((rc = MQTTClient_setCallbacks(mqtt_client, mqtt_client, connlost, mqtt_message_arrived, NULL)) !=
313+
MQTTCLIENT_SUCCESS) {
314+
LOG_ERROR(TAG_MQTT, "Failed to set callbacks, return code %d", rc);
315+
rc = EXIT_FAILURE;
316+
return;
317+
}
318+
mqttClientCreated = true;
315319
}
316320

317321
LOG_DEBUG(TAG_MQTT, "%s %d", __FILE__, __LINE__);
@@ -350,6 +354,8 @@ void mqttStart()
350354

351355
void mqttStop()
352356
{
357+
if(!mqttClientCreated) return;
358+
353359
int rc;
354360
// MQTTClient_disconnectOptions disc_opts = MQTTClient_disconnectOptions_initializer;
355361
// disc_opts.onSuccess = onDisconnect;
@@ -358,6 +364,8 @@ void mqttStop()
358364
LOG_ERROR(TAG_MQTT, "Failed to disconnect, return code %d", rc);
359365
rc = EXIT_FAILURE;
360366
}
367+
MQTTClient_destroy(&mqtt_client);
368+
mqttClientCreated = false;
361369
}
362370

363371
void mqttSetup()

0 commit comments

Comments
 (0)