From 69c0894ecbb29fd1d6c246f34425045c08cdf606 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Sat, 28 Feb 2026 17:00:23 +0800 Subject: [PATCH] [fix] fix device presence status dispatch on login/logout --- src/device_db_manager/device_db_manager.cpp | 76 --------------------- src/presence_manager.cpp | 47 +++++++++---- src/presence_manager.h | 4 ++ 3 files changed, 37 insertions(+), 90 deletions(-) diff --git a/src/device_db_manager/device_db_manager.cpp b/src/device_db_manager/device_db_manager.cpp index c3b54bd..d3c438d 100644 --- a/src/device_db_manager/device_db_manager.cpp +++ b/src/device_db_manager/device_db_manager.cpp @@ -60,12 +60,6 @@ void DeviceDBManager::InitDB() { "online INTEGER NOT NULL," "updated_at INTEGER NOT NULL" ");"; - const char* sql_user_devices = - "CREATE TABLE IF NOT EXISTS user_devices (" - "user_id TEXT NOT NULL," - "device_id TEXT NOT NULL," - "PRIMARY KEY(user_id, device_id)" - ");"; char* err_msg = nullptr; @@ -94,12 +88,6 @@ void DeviceDBManager::InitDB() { sqlite3_free(err_msg); return; } - if (sqlite3_exec(db_, sql_user_devices, nullptr, nullptr, &err_msg) != - SQLITE_OK) { - LOG_ERROR("Failed to create user_devices table: {}", err_msg); - sqlite3_free(err_msg); - return; - } } std::string DeviceDBManager::Sha256(const std::string& str) { @@ -410,70 +398,6 @@ bool DeviceDBManager::UpdatePassword(const std::string& device_id, return success; } -bool DeviceDBManager::SetUserDevices( - const std::string& user_id, const std::vector& device_ids) { - if (db_ == nullptr) { - LOG_ERROR("Database is not initialized in SetUserDevices."); - return false; - } - sqlite3_exec(db_, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr); - const char* del_sql = "DELETE FROM user_devices WHERE user_id = ?;"; - sqlite3_stmt* del_stmt = nullptr; - if (sqlite3_prepare_v2(db_, del_sql, -1, &del_stmt, nullptr) != SQLITE_OK) { - sqlite3_exec(db_, "ROLLBACK;", nullptr, nullptr, nullptr); - return false; - } - sqlite3_bind_text(del_stmt, 1, user_id.c_str(), -1, SQLITE_TRANSIENT); - if (sqlite3_step(del_stmt) != SQLITE_DONE) { - sqlite3_finalize(del_stmt); - sqlite3_exec(db_, "ROLLBACK;", nullptr, nullptr, nullptr); - return false; - } - sqlite3_finalize(del_stmt); - - const char* ins_sql = - "INSERT INTO user_devices (user_id, device_id) VALUES (?, ?);"; - sqlite3_stmt* ins_stmt = nullptr; - if (sqlite3_prepare_v2(db_, ins_sql, -1, &ins_stmt, nullptr) != SQLITE_OK) { - sqlite3_exec(db_, "ROLLBACK;", nullptr, nullptr, nullptr); - return false; - } - for (const auto& id : device_ids) { - sqlite3_bind_text(ins_stmt, 1, user_id.c_str(), -1, SQLITE_TRANSIENT); - sqlite3_bind_text(ins_stmt, 2, id.c_str(), -1, SQLITE_TRANSIENT); - if (sqlite3_step(ins_stmt) != SQLITE_DONE) { - sqlite3_finalize(ins_stmt); - sqlite3_exec(db_, "ROLLBACK;", nullptr, nullptr, nullptr); - return false; - } - sqlite3_reset(ins_stmt); - sqlite3_clear_bindings(ins_stmt); - } - sqlite3_finalize(ins_stmt); - sqlite3_exec(db_, "COMMIT;", nullptr, nullptr, nullptr); - return true; -} - -std::vector DeviceDBManager::GetUserDevices( - const std::string& user_id) { - std::vector devices; - if (db_ == nullptr) { - LOG_ERROR("Database is not initialized in GetUserDevices."); - return devices; - } - const char* sql = "SELECT device_id FROM user_devices WHERE user_id = ?;"; - sqlite3_stmt* stmt = nullptr; - if (sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr) != SQLITE_OK) { - return devices; - } - sqlite3_bind_text(stmt, 1, user_id.c_str(), -1, SQLITE_TRANSIENT); - while (sqlite3_step(stmt) == SQLITE_ROW) { - devices.emplace_back( - reinterpret_cast(sqlite3_column_text(stmt, 0))); - } - sqlite3_finalize(stmt); - return devices; -} bool DeviceDBManager::RemoveDevice(const std::string& device_id) { if (db_ == nullptr) { LOG_ERROR("Database is not initialized in RemoveDevice."); diff --git a/src/presence_manager.cpp b/src/presence_manager.cpp index d59aeb1..4af921d 100644 --- a/src/presence_manager.cpp +++ b/src/presence_manager.cpp @@ -2,6 +2,8 @@ #include +#include "log.h" + void PresenceManager::OnLogin(const std::string& user_id, const std::string& device_id, websocketpp::connection_hdl hdl) { @@ -12,8 +14,7 @@ void PresenceManager::OnLogin(const std::string& user_id, } void PresenceManager::OnLogout(const std::string& device_id) { - std::string user_id; - user_id = device_id; + std::string user_id = device_id; if (db_) { db_->SetDeviceOnline(device_id, false); } @@ -40,15 +41,30 @@ std::vector> PresenceManager::BatchQuery( void PresenceManager::NotifyUserDevices(const std::string& user_id, const std::string& changed_device_id, bool online) { - if (!db_ || !send_msg_) return; - auto devices = db_->GetUserDevices(user_id); - if (devices.empty()) return; - auto statuses = db_->BatchQueryOnline(devices); - std::vector targets; - for (const auto& p : statuses) { - if (p.first == changed_device_id) continue; - if (p.second) { - targets.push_back(p.first); + if (!send_msg_) { + return; + } + + std::vector watchers; + for (const auto& kv : associations_) { + const auto& watcher = kv.first; + const auto& watched_set = kv.second; + if (watched_set.find(changed_device_id) != watched_set.end()) { + watchers.push_back(watcher); + } + } + if (watchers.empty()) { + return; + } + std::vector targets = watchers; + if (db_) { + auto statuses = db_->BatchQueryOnline(watchers); + targets.clear(); + for (const auto& p : statuses) { + if (p.first == changed_device_id) { + continue; + } + if (p.second) targets.push_back(p.first); } } nlohmann::json j = { @@ -56,7 +72,7 @@ void PresenceManager::NotifyUserDevices(const std::string& user_id, {"id", changed_device_id}, {"online", online}, }; - for (auto& id : targets) { + for (const auto& id : targets) { if (send_to_device_) { send_to_device_(id, j); } @@ -65,6 +81,9 @@ void PresenceManager::NotifyUserDevices(const std::string& user_id, void PresenceManager::UpdateUserDevices( const std::string& user_id, const std::vector& device_ids) { - if (!db_) return; - db_->SetUserDevices(user_id, device_ids); + auto& setref = associations_[user_id]; + setref.clear(); + for (const auto& id : device_ids) { + setref.insert(id); + } } diff --git a/src/presence_manager.h b/src/presence_manager.h index 61b88d3..c1f89c6 100644 --- a/src/presence_manager.h +++ b/src/presence_manager.h @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include @@ -50,6 +52,8 @@ class PresenceManager { std::function send_msg_; DeviceDBManager* db_ = nullptr; std::function send_to_device_; + std::unordered_map> + associations_; }; #endif