feat(dashboard): Network summary has each server's port and machine

The dashboard keeps master's server list endpoints and joins them into the
Network summary: its listening port and its machine as a token, since the
summary goes to every open page. The connection list maps the tokens to
addresses for viewers with network_ips. The dashboard reports its web port.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-30 02:13:41 -05:00
parent a93f5f810b
commit b0819df5b6
6 changed files with 124 additions and 15 deletions

View File

@@ -278,11 +278,6 @@ namespace {
{"messages_since", since}, {"routes", routes} };
}
// What open pages get every few seconds (the Network page draws it; Diagnostics reloads on it)
nlohmann::json Summary(int64_t now) {
return NetworkView::Summary(g_History, now, ONLINE_SECONDS, LabelOf);
}
uint64_t AddressSalt() {
static const uint64_t salt = [] {
std::random_device device;
@@ -291,6 +286,19 @@ namespace {
return salt;
}
// Each server's listening port and machine, from master's last server list
NetworkView::Endpoints Endpoints() {
NetworkView::Endpoints endpoints;
std::lock_guard lock(ServerState::g_StatusMutex);
for (const auto& [key, endpoint] : ServerState::g_Endpoints) endpoints[key] = { endpoint.port, endpoint.host };
return endpoints;
}
// What open pages get every few seconds (the Network page draws it; Diagnostics reloads on it)
nlohmann::json Summary(int64_t now) {
return NetworkView::Summary(g_History, now, ONLINE_SECONDS, LabelOf, Endpoints(), AddressSalt());
}
// One server for the Network page's detail panel: what ServerInfo says, its busiest message types each way over the
// last 5 minutes, and its packets and bytes per second over the last 10 minutes (5 second steps)
nlohmann::json NetworkServer(const std::string& key, int64_t now) {
@@ -448,7 +456,7 @@ namespace Traffic {
TrafficStats::Local().SetGauge("workers_threads", [] { return static_cast<double>(Workers::Pool().Threads()); });
Route(eHTTPMethod::GET, "/api/diagnostics/network", Perm(PERMISSION),
"The Network page's live view: every reporting server's packets and bytes per second over its last report, its split by peer (clients, master, other servers; null for servers too old to report one), HTTP requests, RakNet link statistics and gauges",
"The Network page's live view: every reporting server's packets and bytes per second over its last report, its split by peer (clients, master, other servers; null for servers too old to report one), HTTP requests, RakNet link statistics, gauges, its listening port and its machine (host: a token; the connections route maps it to the address with network_ips)",
[](HTTPReply& reply, const HTTPContext&) {
JsonSuccess(reply, Summary(TrafficStats::Now()));
});
@@ -462,9 +470,9 @@ namespace Traffic {
});
Route(eHTTPMethod::GET, "/api/diagnostics/network/connections", Perm(PERMISSION),
"Every server's remote ends from its last report, grouped by address (game clients' RakNet connections, HTTP clients, server links), with rates, ping and the logged-in player. Addresses only with network_ips; otherwise a token per address",
"Every server's remote ends from its last report, grouped by address (game clients' RakNet connections, HTTP clients, server links), with rates, ping and the logged-in player. Addresses and remote ports only with network_ips; otherwise a token per address. hosts: each machine token of the summary to its address (network_ips only)",
[](HTTPReply& reply, const HTTPContext& context) {
JsonSuccess(reply, NetworkView::Connections(g_History, TrafficStats::Now(), ONLINE_SECONDS, Can(context, IPS_PERMISSION), AddressSalt(), LabelOf));
JsonSuccess(reply, NetworkView::Connections(g_History, TrafficStats::Now(), ONLINE_SECONDS, Can(context, IPS_PERMISSION), AddressSalt(), LabelOf, Endpoints()));
});
Route(eHTTPMethod::GET, "/api/diagnostics/traffic", Perm(PERMISSION),