diff --git a/client.cpp b/client.cpp index e2889aa..0b845ce 100644 --- a/client.cpp +++ b/client.cpp @@ -49,11 +49,11 @@ Client::Client(int fd, std::shared_ptr threadData, SSL *ssl, bool we Client::~Client() { + std::shared_ptr &store = getThreadData()->getSubscriptionStore(); + // Will payload can be empty, apparently. if (!will_topic.empty()) { - std::shared_ptr &store = getThreadData()->getSubscriptionStore(); - Publish will(will_topic, will_payload, will_qos); will.retain = will_retain; const MqttPacket willPacket(will); @@ -69,6 +69,12 @@ Client::~Client() if (epoll_ctl(threadData->epollfd, EPOLL_CTL_DEL, fd, NULL) != 0) logger->logf(LOG_ERR, "Removing fd %d of client '%s' from epoll produced error: %s", fd, repr().c_str(), strerror(errno)); close(fd); + + // MQTT-3.1.2-6 + if (cleanSession) + { + store->removeSession(clientid); + } } bool Client::isSslAccepted() const diff --git a/subscriptionstore.cpp b/subscriptionstore.cpp index cc88461..62a2c31 100644 --- a/subscriptionstore.cpp +++ b/subscriptionstore.cpp @@ -492,6 +492,20 @@ int SubscriptionNode::cleanSubscriptions() return subscribers.size() + subscribersLeftInChildren; } +void SubscriptionStore::removeSession(const std::string &clientid) +{ + RWLockGuard lock_guard(&subscriptionsRwlock); + lock_guard.wrlock(); + + logger->logf(LOG_DEBUG, "Removing session of client '%s'.", clientid.c_str()); + + auto session_it = sessionsById.begin(); + if (session_it != sessionsById.end()) + { + sessionsById.erase(session_it); + } +} + // This is not MQTT compliant, but the standard doesn't keep real world constraints into account. void SubscriptionStore::removeExpiredSessionsClients(int expireSessionsAfterSeconds) { diff --git a/subscriptionstore.h b/subscriptionstore.h index aa5e63f..dec8e57 100644 --- a/subscriptionstore.h +++ b/subscriptionstore.h @@ -118,6 +118,7 @@ public: void setRetainedMessage(const std::string &topic, const std::vector &subtopics, const std::string &payload, char qos); + void removeSession(const std::string &clientid); void removeExpiredSessionsClients(int expireSessionsAfterSeconds); int64_t getRetainedMessageCount() const;