From 0f586d98db552d43566a4d95df1cbdcd9757f1fb Mon Sep 17 00:00:00 2001 From: Justaphf Date: Thu, 11 Jun 2026 21:51:41 -0400 Subject: [PATCH] #429 Fix upgraded clients not visible to remote clients Root cause was that the outgoing websocket connection lost its only strong owner in `a271d5d`. The weak reference dies before the handshake, silently, because every async callback is a WeakCall and `Account::connect()` sets `STATE_CONNECTED` in a fire-and-forget manner. --- src/cbang/ws/Websocket.cpp | 18 ++++++++++++------ src/cbang/ws/Websocket.h | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/cbang/ws/Websocket.cpp b/src/cbang/ws/Websocket.cpp index a6d21f3d3..ac24be855 100644 --- a/src/cbang/ws/Websocket.cpp +++ b/src/cbang/ws/Websocket.cpp @@ -71,9 +71,11 @@ void Websocket::connect(HTTP::Client &client, const URI &uri) { start(); } else { + // Release refs first so a reconnect from onClose() is not clobbered + outConn.release(); + connection.release(); onClose(WS_STATUS_NONE, SSTR("Connection failed: error=" << error << " code=" << code)); - connection.release(); } }; @@ -88,7 +90,11 @@ void Websocket::connect(HTTP::Client &client, const URI &uri) { req->outSet("Upgrade", "websocket"); req->outSet("Connection", "upgrade"); - connection = client.send(req); + // Hold a strong reference to the outgoing connection; other refs are weak + outConn = client.send(req); + connection = outConn; + // Cache ID like upgrade() does, since the weak ref may not outlive us + id = outConn->getID(); } @@ -439,10 +445,10 @@ void Websocket::shutdown() { SmartPointer self = this; SmartPointer conn = connection; - if (conn.isSet()) { - connection.release(); - conn->close(); - } + // Clear members first; conn->close() callbacks may re-enter this class + outConn.release(); + connection.release(); + if (conn.isSet()) conn->close(); if (active) { active = false; diff --git a/src/cbang/ws/Websocket.h b/src/cbang/ws/Websocket.h index 8288034ac..c0d951dcb 100644 --- a/src/cbang/ws/Websocket.h +++ b/src/cbang/ws/Websocket.h @@ -50,6 +50,7 @@ namespace cb { namespace WS { class Websocket : virtual public RefCounted, public Enum { SmartPointer::Weak connection; + SmartPointer outConn; uint64_t id = ~0; bool active = false;