diff --git a/impl/wsLibHttpClient/NWebsocketLibHC.cpp b/impl/wsLibHttpClient/NWebsocketLibHC.cpp index ca820837..c0a93c67 100644 --- a/impl/wsLibHttpClient/NWebsocketLibHC.cpp +++ b/impl/wsLibHttpClient/NWebsocketLibHC.cpp @@ -193,6 +193,7 @@ void NWebsocketLibHC::connect(const std::string& url, NRtTransportType type) { HCWebSocketSetMaxReceiveBufferSize(ws, 1024 * 1024); #endif m_ws.reset(ws); + _state.store(State::Connecting, std::memory_order_relaxed); } auto* asyncBlock = new XAsyncBlock{}; @@ -211,8 +212,10 @@ void NWebsocketLibHC::connect(const std::string& url, NRtTransportType type) { if (self->m_ws /*&& self->m_ws.get() == result.websocket*/) { if (SUCCEEDED(result.errorCode)) { self->_lastReceivedMessageTimeMs = getUnixTimestampMs(); + self->_state.store(State::Connected, std::memory_order_relaxed); self->fireOnConnected(); } else { + self->_state.store(State::Disconnected, std::memory_order_relaxed); self->fireOnError("Websocket connection error"); } } else { @@ -223,6 +226,7 @@ void NWebsocketLibHC::connect(const std::string& url, NRtTransportType type) { "User requested disconnect, while connection was in progress. Ignoring connection result."); } } else { + self->_state.store(State::Disconnected, std::memory_order_relaxed); self->fireOnError("Websocket connection error: HCGetWebsocketConnectResult failed"); } }; @@ -238,9 +242,12 @@ void NWebsocketLibHC::disconnect() { m_ws.reset(nullptr); _connected = false; // white lie, we didn't receive close confirmation from server yet + _state.store(State::Disconnected, std::memory_order_relaxed); } } +bool NWebsocketLibHC::isConnecting() const { return _state.load(std::memory_order_relaxed) == State::Connecting; } + void NWebsocketLibHC::setActivityTimeout(uint32_t timeoutMs) { _activityTimeoutMs = timeoutMs; } uint32_t NWebsocketLibHC::getActivityTimeout() const { return _activityTimeoutMs; } @@ -331,6 +338,7 @@ void __stdcall NWebsocketLibHC::ws_on_close(HCWebsocketHandle ws, HCWebSocketClo // Here we check that notification is for the "active" socket, not a previously closed one to avoid race if (self->m_ws && self->m_ws.get() == ws) { self->m_ws.reset(nullptr); + self->_state.store(State::Disconnected, std::memory_order_relaxed); NRtClientDisconnectInfo info; info.code = code; info.remote = true; diff --git a/impl/wsLibHttpClient/NWebsocketLibHC.h b/impl/wsLibHttpClient/NWebsocketLibHC.h index fe3ba679..6584d4cc 100644 --- a/impl/wsLibHttpClient/NWebsocketLibHC.h +++ b/impl/wsLibHttpClient/NWebsocketLibHC.h @@ -16,6 +16,7 @@ #pragma once +#include #include #include #include @@ -36,10 +37,12 @@ class NWebsocketLibHC final : public NRtTransportInterface { void disconnect() override; bool send(const NBytes& data) override; - bool isConnecting() const override { return false; }; + bool isConnecting() const override; private: explicit NWebsocketLibHC(XTaskQueueHandle q); + + enum class State { Disconnected, Connecting, Connected }; // void submit_cb(const NHttpResponseCallback &cb, int statusCode, std::string body, std::string err = "") // noexcept; HRESULT NWebsocketLibHC::prep_hc_call(const NHttpRequest& req, std::unique_ptr& call); @@ -50,6 +53,7 @@ class NWebsocketLibHC final : public NRtTransportInterface { bool m_is_binary; uint32_t _activityTimeoutMs = 0; uint64_t _lastReceivedMessageTimeMs; + std::atomic _state{State::Disconnected}; static void __stdcall ws_on_text_msg(HCWebsocketHandle ws, const char* str, void* self); static void __stdcall ws_on_binary_msg(HCWebsocketHandle ws, const uint8_t* bytes, uint32_t size, void* self);