mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-16 08:10:58 +00:00
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:
@@ -109,10 +109,10 @@ func (j *NodeTrafficSyncJob) Run() {
|
||||
lastOnline = map[string]int64{}
|
||||
}
|
||||
|
||||
// Prune stale local-online entries (no local active emails to add here —
|
||||
// only the local xray poll feeds those) so a stopped local xray's clients
|
||||
// still age out between traffic polls.
|
||||
j.inboundService.RefreshLocalOnlineClients(nil)
|
||||
// Prune stale local-online entries (no local active emails or inbound tags
|
||||
// to add here — only the local xray poll feeds those) so a stopped local
|
||||
// xray's clients and inbounds still age out between traffic polls.
|
||||
j.inboundService.RefreshLocalOnlineClients(nil, nil)
|
||||
|
||||
if !websocket.HasClients() {
|
||||
return
|
||||
@@ -123,9 +123,10 @@ func (j *NodeTrafficSyncJob) Run() {
|
||||
online = []string{}
|
||||
}
|
||||
websocket.BroadcastTraffic(map[string]any{
|
||||
"onlineClients": online,
|
||||
"onlineByNode": j.inboundService.GetOnlineClientsByNode(),
|
||||
"lastOnlineMap": lastOnline,
|
||||
"onlineClients": online,
|
||||
"onlineByNode": j.inboundService.GetOnlineClientsByNode(),
|
||||
"activeInbounds": j.inboundService.GetActiveInboundsByNode(),
|
||||
"lastOnlineMap": lastOnline,
|
||||
})
|
||||
|
||||
clientStats := map[string]any{}
|
||||
|
||||
@@ -82,7 +82,18 @@ func (j *XrayTrafficJob) Run() {
|
||||
activeEmails = append(activeEmails, ct.Email)
|
||||
}
|
||||
}
|
||||
j.inboundService.RefreshLocalOnlineClients(activeEmails)
|
||||
// Pair the email signal with the inbound tags that moved bytes this poll.
|
||||
// Xray's user>>>email counter aggregates across every inbound a client is
|
||||
// attached to, so an online email alone can't say which inbound it used —
|
||||
// gating the per-inbound view on these tags keeps a multi-inbound client
|
||||
// off inbounds that saw no traffic. See issue #4859.
|
||||
activeInboundTags := make([]string, 0, len(traffics))
|
||||
for _, tr := range traffics {
|
||||
if tr != nil && tr.IsInbound && tr.Up+tr.Down > 0 {
|
||||
activeInboundTags = append(activeInboundTags, tr.Tag)
|
||||
}
|
||||
}
|
||||
j.inboundService.RefreshLocalOnlineClients(activeEmails, activeInboundTags)
|
||||
|
||||
if !websocket.HasClients() {
|
||||
return
|
||||
@@ -97,6 +108,7 @@ func (j *XrayTrafficJob) Run() {
|
||||
"clientTraffics": clientTraffics,
|
||||
"onlineClients": onlineClients,
|
||||
"onlineByNode": j.inboundService.GetOnlineClientsByNode(),
|
||||
"activeInbounds": j.inboundService.GetActiveInboundsByNode(),
|
||||
"lastOnlineMap": lastOnlineMap,
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user