Implement unsubscribe and drain in publish
This commit is contained in:
+36
-2
@@ -120,6 +120,11 @@ private:
|
|||||||
|
|
||||||
/* Should be getData and commit? */
|
/* Should be getData and commit? */
|
||||||
void publish(Topic *iterator, size_t start, size_t stop, std::string_view topic, std::string_view message) {
|
void publish(Topic *iterator, size_t start, size_t stop, std::string_view topic, std::string_view message) {
|
||||||
|
/* If we already have 64 triggered topics make sure to drain it here */
|
||||||
|
if (numTriggeredTopics == 64) {
|
||||||
|
drain();
|
||||||
|
}
|
||||||
|
|
||||||
for (; stop != std::string::npos; start = stop + 1) {
|
for (; stop != std::string::npos; start = stop + 1) {
|
||||||
stop = topic.find('/', start);
|
stop = topic.find('/', start);
|
||||||
std::string_view segment = topic.substr(start, stop - start);
|
std::string_view segment = topic.substr(start, stop - start);
|
||||||
@@ -235,10 +240,39 @@ public:
|
|||||||
messageId++;
|
messageId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rarely used, probably */
|
/* Returns whether we were subscribed prior */
|
||||||
void unsubscribe(std::string_view topic, Subscriber *subscriber) {
|
bool unsubscribe(std::string_view topic, Subscriber *subscriber) {
|
||||||
/* Subscribers are likely to have very few subscriptions (20 or fewer) */
|
/* Subscribers are likely to have very few subscriptions (20 or fewer) */
|
||||||
|
if (subscriber) {
|
||||||
|
/* Lookup exact Topic ptr from string */
|
||||||
|
Topic *iterator = root;
|
||||||
|
for (size_t start = 0, stop = 0; stop != std::string::npos; start = stop + 1) {
|
||||||
|
stop = topic.find('/', start);
|
||||||
|
std::string_view segment = topic.substr(start, stop - start);
|
||||||
|
|
||||||
|
std::map<std::string_view, Topic *>::iterator it = iterator->children.find(segment);
|
||||||
|
if (it == iterator->children.end()) {
|
||||||
|
/* This topic does not even exist */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator = it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try and remove this topic from our list */
|
||||||
|
for (auto it = subscriber->subscriptions.begin(); it != subscriber->subscriptions.end(); it++) {
|
||||||
|
if (*it == iterator) {
|
||||||
|
/* Remove topic ptr from our list */
|
||||||
|
subscriber->subscriptions.erase(it);
|
||||||
|
|
||||||
|
/* Remove us from Topic's subs */
|
||||||
|
iterator->subs.erase(subscriber);
|
||||||
|
trimTree(iterator);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can be called with nullptr, ignore it then */
|
/* Can be called with nullptr, ignore it then */
|
||||||
|
|||||||
@@ -154,6 +154,17 @@ public:
|
|||||||
webSocketContextData->topicTree.subscribe(topic, webSocketData->subscriber);
|
webSocketContextData->topicTree.subscribe(topic, webSocketData->subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unsubscribe from a topic, returns true if we were subscribed */
|
||||||
|
bool unsubscribe(std::string_view topic) {
|
||||||
|
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL,
|
||||||
|
(us_socket_context_t *) us_socket_context(SSL, (us_socket_t *) this)
|
||||||
|
);
|
||||||
|
|
||||||
|
WebSocketData *webSocketData = (WebSocketData *) us_socket_ext(SSL, (us_socket_t *) this);
|
||||||
|
|
||||||
|
return webSocketContextData->topicTree.unsubscribe(topic, webSocketData->subscriber);
|
||||||
|
}
|
||||||
|
|
||||||
/* Publish a message to a topic according to MQTT rules and syntax */
|
/* Publish a message to a topic according to MQTT rules and syntax */
|
||||||
void publish(std::string_view topic, std::string_view message, OpCode opCode = OpCode::TEXT, bool compress = false) {
|
void publish(std::string_view topic, std::string_view message, OpCode opCode = OpCode::TEXT, bool compress = false) {
|
||||||
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL,
|
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL,
|
||||||
|
|||||||
Reference in New Issue
Block a user