fix(online): scope per-inbound online to inbounds that carried traffic

Multi-inbound clients showed online on every inbound they were attached to. Xray's user-level traffic stat aggregates across all inbounds a client belongs to, so the email signal alone can't say which inbound was used.

Pair it with the inbound-level traffic signal under the same 20s grace and gate the per-inbound rollup on it: a client only shows online on inbounds that actually moved bytes this window. Remote nodes report no per-inbound activity and stay ungated (no regression). Adds GetActiveInboundsByNode, the activeInbounds WS field and POST /panel/api/clients/activeInbounds.

Fixes #4859
This commit is contained in:
MHSanaei
2026-06-03 16:19:00 +02:00
parent 5fb18b8819
commit ef8882a5c0
11 changed files with 224 additions and 30 deletions
+6
View File
@@ -675,6 +675,12 @@ export const sections: readonly Section[] = [
summary: 'Online client emails grouped by the node that reported them. The local panel uses key "0"; each remote node uses its node id. Lets the inbounds page show online status per node instead of merging every node together.',
response: '{\n "success": true,\n "obj": {\n "0": ["user1"],\n "3": ["user1", "user2"]\n }\n}',
},
{
method: 'POST',
path: '/panel/api/clients/activeInbounds',
summary: 'Inbound tags that carried traffic within the heartbeat window, grouped by node (local panel uses key "0"). Pairs with onlinesByNode so the inbounds page only marks a multi-inbound client online on the inbounds it actually used. Nodes that do not report per-inbound activity are absent.',
response: '{\n "success": true,\n "obj": {\n "0": ["inbound-443", "inbound-8443"]\n }\n}',
},
{
method: 'POST',
path: '/panel/api/clients/lastOnline',