[fix] exclude clone clients from online device stats

This commit is contained in:
dijunkun committed 2026-05-30 01:24:17 +08:00
1 parent 68d496a9b2
commit 22599bc7db
5 files changed
+66 -15

No files matched your search

+1 -1
View File
@@ -147,7 +147,7 @@ curl --cacert /var/lib/crossdesk/certs/api.crossdesk.cn_root.crt \
}
```
- `online_device_count`:当前在线设备数,不包含临时 `web-*` 客户端
- `online_device_count`:当前在线设备数,不包含临时 `web-*` 客户端和 `C-*` 分身客户端
- `online_web_client_count`:当前在线 Web 客户端数,仅统计临时 `web-*` 客户端
- `active_connection_count`:当前处于连接中的会话数,按已加入传输的客户端连接数统计
- 响应已带 `Access-Control-Allow-Origin: *`,可直接被网页端 `fetch` 调用
+1 -1
View File
@@ -146,7 +146,7 @@ The `/api/stats` path is also supported. Example response:
}
```
- `online_device_count`: Number of online devices, excluding temporary `web-*` clients
- `online_device_count`: Number of online devices, excluding temporary `web-*` clients and `C-*` clone clients
- `online_web_client_count`: Number of online web clients, counting only temporary `web-*` clients
- `active_connection_count`: Number of active in-progress connections, counted by joined guest connections in transmissions
- The response includes `Access-Control-Allow-Origin: *`, so it can be called directly from browser `fetch`
+3 -1
View File
@@ -502,7 +502,9 @@ int DeviceDBManager::GetOnlineDeviceCount() {
const char* sql =
"SELECT COUNT(*) FROM device_presence "
"WHERE online = 1 AND device_id NOT LIKE 'web-%';";
"WHERE online = 1 "
"AND device_id NOT LIKE 'web-%' "
"AND device_id NOT LIKE 'C-%';";
sqlite3_stmt* stmt = nullptr;
if (sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr) != SQLITE_OK) {
+7 -3
View File
@@ -10,8 +10,12 @@ bool IsWebClient(const std::string& device_id) {
return device_id.rfind("web-", 0) == 0;
}
bool IsCloneClient(const std::string& device_id) {
return device_id.rfind("C-", 0) == 0;
}
bool ShouldTrackOnlineDevice(const std::string& device_id) {
return !IsWebClient(device_id);
return !IsWebClient(device_id) && !IsCloneClient(device_id);
}
} // namespace
@@ -23,7 +27,7 @@ void PresenceManager::OnLogin(const std::string& user_id,
std::lock_guard<std::mutex> lock(online_devices_mutex_);
if (ShouldTrackOnlineDevice(device_id)) {
online_devices_.insert(device_id);
} else {
} else if (IsWebClient(device_id)) {
online_web_clients_.insert(device_id);
}
}
@@ -39,7 +43,7 @@ void PresenceManager::OnLogout(const std::string& device_id) {
std::lock_guard<std::mutex> lock(online_devices_mutex_);
if (ShouldTrackOnlineDevice(device_id)) {
online_devices_.erase(device_id);
} else {
} else if (IsWebClient(device_id)) {
online_web_clients_.erase(device_id);
}
}
+54 -9
View File
@@ -1,30 +1,75 @@
#include "presence_manager.h"
#include <chrono>
#include <filesystem>
#include <iostream>
#include <string>
#include "device_db_manager.h"
int main() {
PresenceManager presence;
websocketpp::connection_hdl hdl;
int failures = 0;
auto expect = [&failures](bool condition) {
auto expect = [&failures](bool condition, const std::string& message) {
if (!condition) {
std::cerr << "FAIL: " << message << std::endl;
++failures;
}
};
expect(presence.GetOnlineDeviceCount() == 0);
expect(presence.GetOnlineWebClientCount() == 0);
expect(presence.GetOnlineDeviceCount() == 0,
"initial online device count is zero");
expect(presence.GetOnlineWebClientCount() == 0,
"initial online web client count is zero");
presence.OnLogin("device-1", "device-1", hdl);
expect(presence.GetOnlineDeviceCount() == 1);
expect(presence.GetOnlineWebClientCount() == 0);
expect(presence.GetOnlineDeviceCount() == 1,
"regular device increments online device count");
expect(presence.GetOnlineWebClientCount() == 0,
"regular device does not increment web client count");
presence.OnLogin("web-1", "web-1", hdl);
expect(presence.GetOnlineDeviceCount() == 1);
expect(presence.GetOnlineWebClientCount() == 1);
expect(presence.GetOnlineDeviceCount() == 1,
"web client does not increment online device count");
expect(presence.GetOnlineWebClientCount() == 1,
"web client increments web client count");
presence.OnLogin("C-000000", "C-000000", hdl);
expect(presence.GetOnlineDeviceCount() == 1,
"clone client does not increment online device count");
expect(presence.GetOnlineWebClientCount() == 1,
"clone client does not increment web client count");
presence.OnLogout("C-000000");
expect(presence.GetOnlineDeviceCount() == 1,
"clone logout leaves online device count unchanged");
expect(presence.GetOnlineWebClientCount() == 1,
"clone logout leaves web client count unchanged");
presence.OnLogout("web-1");
expect(presence.GetOnlineDeviceCount() == 1);
expect(presence.GetOnlineWebClientCount() == 0);
expect(presence.GetOnlineDeviceCount() == 1,
"web logout leaves online device count unchanged");
expect(presence.GetOnlineWebClientCount() == 0,
"web logout decrements web client count");
const auto db_path =
std::filesystem::temp_directory_path() /
("crossdesk_presence_manager_test_" +
std::to_string(std::chrono::steady_clock::now()
.time_since_epoch()
.count()) +
".db");
{
DeviceDBManager db(db_path.string());
db.SetDeviceOnline("device-1", true);
db.SetDeviceOnline("web-1", true);
db.SetDeviceOnline("C-000000", true);
expect(db.GetOnlineDeviceCount() == 1,
"database online device count excludes web and clone clients");
}
std::filesystem::remove(db_path);
return failures == 0 ? 0 : 1;
}