From 3f81f874de83c61a13b508c67ffa4ac435e9fd06 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 28 May 2019 22:13:22 +0100 Subject: [PATCH] Fix persistent Websockets clients not receiving messages. This occurs after they reconnect, having sent DISCONNECT on a previous session. Closes #1227. Thanks to usernametaken. --- ChangeLog.txt | 2 ++ src/loop.c | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 39d1329d..33504027 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -18,6 +18,8 @@ Broker: #1276. - Add 'extern "C"' on mosquitto_broker.h and mosquitto_plugin.h for C++ plugin writing. Closes #1290. +- Fix persistent Websockets clients not receiving messages after they + reconnect, having sent DISCONNECT on a previous session. Closes #1227. Client library: - Fix typo causing build error on Windows when building without TLS support. diff --git a/src/loop.c b/src/loop.c index fc18399e..50959599 100644 --- a/src/loop.c +++ b/src/loop.c @@ -614,12 +614,19 @@ void do_disconnect(struct mosquitto_db *db, struct mosquitto *context, int reaso #ifdef WITH_EPOLL struct epoll_event ev; #endif +#ifdef WITH_WEBSOCKETS + bool is_duplicate = false; +#endif if(context->state == mosq_cs_disconnected){ return; } #ifdef WITH_WEBSOCKETS if(context->wsi){ + if(context->state == mosq_cs_duplicate){ + is_duplicate = true; + } + if(context->state != mosq_cs_disconnecting && context->state != mosq_cs_disconnect_with_will){ context__set_state(context, mosq_cs_disconnect_ws); } @@ -636,7 +643,15 @@ void do_disconnect(struct mosquitto_db *db, struct mosquitto *context, int reaso context->sock = INVALID_SOCKET; context->pollfd_index = -1; } - context__remove_from_by_id(db, context); + if(is_duplicate){ + /* This occurs if another client is taking over the same client id. + * It is important to remove this from the by_id hash here, so it + * doesn't leave us with multiple clients in the hash with the same + * id. Websockets doesn't actually close the connection here, + * unlike for normal clients, which means there is extra time when + * there could be two clients with the same id in the hash. */ + context__remove_from_by_id(db, context); + } }else #endif {