diff --git a/README.md b/README.md index e22b23a..a9f4914 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Simple, secure1 & standards compliant2 web server for the most demanding3 of applications. Read more...

- Language grade: C/C++ +

diff --git a/src/TopicTree.h b/src/TopicTree.h index b8a80bf..88788a6 100644 --- a/src/TopicTree.h +++ b/src/TopicTree.h @@ -158,7 +158,7 @@ public: } /* Subscribe fails if we already are subscribed */ - bool subscribe(Subscriber *s, std::string_view topic) { + Topic *subscribe(Subscriber *s, std::string_view topic) { /* Notify user that they are doing something wrong here */ checkIteratingSubscriber(s); @@ -173,16 +173,16 @@ public: /* Insert us in topic, insert topic in us */ auto [it, inserted] = s->topics.insert(topicPtr); if (!inserted) { - return false; + return nullptr; } topicPtr->insert(s); /* Success */ - return true; + return topicPtr; } - /* Returns ok, last */ - std::pair unsubscribe(Subscriber *s, std::string_view topic) { + /* Returns ok, last, newCount */ + std::tuple unsubscribe(Subscriber *s, std::string_view topic) { /* Notify user that they are doing something wrong here */ checkIteratingSubscriber(s); @@ -190,17 +190,19 @@ public: Topic *topicPtr = lookupTopic(topic); if (!topicPtr) { /* If the topic doesn't exist we are assumed to still be subscribers of something */ - return {false, false}; + return {false, false, -1}; } /* Erase from our list first */ if (s->topics.erase(topicPtr) == 0) { - return {false, false}; + return {false, false, -1}; } /* Remove us from topic */ topicPtr->erase(s); + int newCount = topicPtr->size(); + /* If there is no subscriber to this topic, remove it */ if (!topicPtr->size()) { /* Unique_ptr deletes the topic */ @@ -208,7 +210,7 @@ public: } /* If we don't hold any topics we are to be freed altogether */ - return {true, topics.size() == 0}; + return {true, s->topics.size() == 0, newCount}; } /* Factory function for creating a Subscriber */ diff --git a/src/WebSocket.h b/src/WebSocket.h index 682ae11..be87544 100644 --- a/src/WebSocket.h +++ b/src/WebSocket.h @@ -195,6 +195,13 @@ public: /* Set shorter timeout (use ping-timeout) to avoid long hanging sockets after end() on broken connections */ Super::timeout(webSocketContextData->idleTimeoutComponents.second); + /* At this point we iterate all currently held subscriptions and emit an event for all of them */ + if (webSocketContextData->subscriptionHandler) { + for (Topic *t : webSocketData->subscriber->topics) { + webSocketContextData->subscriptionHandler(this, t->name, (int) t->size() - 1, (int) t->size()); + } + } + /* Make sure to unsubscribe from any pub/sub node at exit */ webSocketContextData->topicTree->freeSubscriber(webSocketData->subscriber); webSocketData->subscriber = nullptr; @@ -234,7 +241,11 @@ public: } /* Cannot return numSubscribers as this is only for this particular websocket context */ - webSocketContextData->topicTree->subscribe(webSocketData->subscriber, topic); + Topic *topicOrNull = webSocketContextData->topicTree->subscribe(webSocketData->subscriber, topic); + if (topicOrNull && webSocketContextData->subscriptionHandler) { + /* Emit this socket, the topic, new count, old count */ + webSocketContextData->subscriptionHandler(this, topic, (int) topicOrNull->size(), (int) topicOrNull->size() - 1); + } /* Subscribe always succeeds */ return true; @@ -251,7 +262,11 @@ public: if (!webSocketData->subscriber) { return false; } /* Cannot return numSubscribers as this is only for this particular websocket context */ - auto [ok, last] = webSocketContextData->topicTree->unsubscribe(webSocketData->subscriber, topic); + auto [ok, last, newCount] = webSocketContextData->topicTree->unsubscribe(webSocketData->subscriber, topic); + /* Emit subscription event if last */ + if (ok && webSocketContextData->subscriptionHandler) { + webSocketContextData->subscriptionHandler(this, topic, newCount, newCount + 1); + } /* Free us as subscribers if we unsubscribed from our last topic */ if (ok && last) { diff --git a/uSockets b/uSockets index 3cd8709..760a024 160000 --- a/uSockets +++ b/uSockets @@ -1 +1 @@ -Subproject commit 3cd87094c6dc2e158221a3e25dcefde0b8093ca7 +Subproject commit 760a0243c77272df2225fcd50acfc0b1d7ffff0d