From 0f034d6da3e6d0a91bbe09717cb33aaf3a3ed747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= Date: Mon, 19 May 2025 12:11:09 +0200 Subject: [PATCH 10/13] http: add optional callbacks to EventStream Organization: Wires In some cases, it might be useful to have a callback that is called when the client disconnects or when the connection is lost. For us, this will be useful in the future subscribed notifications implementation where we would like to clean up stuff after client disconnects. Change-Id: Icfc2959e38b812b7c18f45976415209b29151c7b Signed-off-by: Joachim Wiberg --- src/http/EventStream.cpp | 18 +++++++++++++++--- src/http/EventStream.h | 10 ++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/http/EventStream.cpp b/src/http/EventStream.cpp index 8703dad..0a974d4 100644 --- a/src/http/EventStream.cpp +++ b/src/http/EventStream.cpp @@ -25,11 +25,15 @@ EventStream::EventStream(const server::request& req, Termination& termination, EventSignal& signal, const std::chrono::seconds keepAlivePingInterval, - const std::optional& initialEvent) + const std::optional& initialEvent, + const std::function& onTerminationCb, + const std::function& onClientDisconnectedCb) : res{res} , ping{res.io_service()} , peer{peer_from_request(req)} , m_keepAlivePingInterval(keepAlivePingInterval) + , onTerminationCb(onTerminationCb) + , onClientDisconnectedCb(onClientDisconnectedCb) { if (initialEvent) { enqueue(FIELD_DATA, *initialEvent); @@ -41,6 +45,9 @@ EventStream::EventStream(const server::request& req, terminateSub = termination.connect([this]() { spdlog::trace("{}: will terminate", peer); + if (this->onTerminationCb) { + this->onTerminationCb(); + } std::lock_guard lock{mtx}; if (state == Closed) { // we are late to the party, res is already gone return; @@ -80,6 +87,9 @@ void EventStream::activate() myself->eventSub.disconnect(); myself->terminateSub.disconnect(); myself->state = Closed; + if (myself->onClientDisconnectedCb) { + myself->onClientDisconnectedCb(); + } }); res.end([myself](uint8_t* destination, std::size_t len, uint32_t* data_flags) { @@ -187,9 +197,11 @@ std::shared_ptr EventStream::create(const nghttp2::asio_http2::serv Termination& terminate, EventSignal& signal, const std::chrono::seconds keepAlivePingInterval, - const std::optional& initialEvent) + const std::optional& initialEvent, + const std::function& onTerminationCb, + const std::function& onClientDisconnectedCb) { - auto stream = std::shared_ptr(new EventStream(req, res, terminate, signal, keepAlivePingInterval, initialEvent)); + auto stream = std::shared_ptr(new EventStream(req, res, terminate, signal, keepAlivePingInterval, initialEvent, onTerminationCb, onClientDisconnectedCb)); stream->activate(); return stream; } diff --git a/src/http/EventStream.h b/src/http/EventStream.h index ef0a002..87d8c82 100644 --- a/src/http/EventStream.h +++ b/src/http/EventStream.h @@ -36,7 +36,9 @@ public: Termination& terminate, EventSignal& signal, const std::chrono::seconds keepAlivePingInterval, - const std::optional& initialEvent = std::nullopt); + const std::optional& initialEvent = std::nullopt, + const std::function& onTerminationCb = std::function(), + const std::function& onClientDisconnectedCb = std::function()); private: const nghttp2::asio_http2::server::response& res; @@ -54,6 +56,8 @@ private: boost::signals2::scoped_connection eventSub, terminateSub; const std::string peer; const std::chrono::seconds m_keepAlivePingInterval; + std::function onTerminationCb; ///< optional callback when the stream is terminated + std::function onClientDisconnectedCb; ///< optional callback invoked in client.on_close() size_t send_chunk(uint8_t* destination, std::size_t len, uint32_t* data_flags); ssize_t process(uint8_t* destination, std::size_t len, uint32_t* data_flags); @@ -66,7 +70,9 @@ protected: Termination& terminate, EventSignal& signal, const std::chrono::seconds keepAlivePingInterval, - const std::optional& initialEvent = std::nullopt); + const std::optional& initialEvent = std::nullopt, + const std::function& onTerminationCb = std::function(), + const std::function& onClientDisconnectedCb = std::function()); void activate(); }; } -- 2.43.0