|
|
@@ -1539,6 +1539,13 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
|
|
|
|
|
|
const resetGracePeriodMs int64 = 30000
|
|
|
|
|
|
+// onlineGracePeriodMs must comfortably exceed the 5s traffic-poll interval —
|
|
|
+// Xray's stats counters often report a zero delta for an active session across
|
|
|
+// a single poll, so a 5s grace would still drop the client on the next tick.
|
|
|
+// ~4 polls of slack keeps idle-but-connected clients visible without lingering
|
|
|
+// long after a real disconnect.
|
|
|
+const onlineGracePeriodMs int64 = 20000
|
|
|
+
|
|
|
func (s *InboundService) SetRemoteTraffic(nodeID int, snap *runtime.TrafficSnapshot) (bool, error) {
|
|
|
var structuralChange bool
|
|
|
err := submitTrafficWrite(func() error {
|
|
|
@@ -1880,15 +1887,9 @@ func (s *InboundService) addInboundTraffic(tx *gorm.DB, traffics []*xray.Traffic
|
|
|
|
|
|
func (s *InboundService) addClientTraffic(tx *gorm.DB, traffics []*xray.ClientTraffic) (err error) {
|
|
|
if len(traffics) == 0 {
|
|
|
- // Empty onlineUsers
|
|
|
- if p != nil {
|
|
|
- p.SetOnlineClients(make([]string, 0))
|
|
|
- }
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
- onlineClients := make([]string, 0)
|
|
|
-
|
|
|
emails := make([]string, 0, len(traffics))
|
|
|
for _, traffic := range traffics {
|
|
|
emails = append(emails, traffic.Email)
|
|
|
@@ -1931,14 +1932,10 @@ func (s *InboundService) addClientTraffic(tx *gorm.DB, traffics []*xray.ClientTr
|
|
|
dbClientTraffics[dbTraffic_index].Down += t.Down
|
|
|
dbClientTraffics[dbTraffic_index].AllTime += t.Up + t.Down
|
|
|
if t.Up+t.Down > 0 {
|
|
|
- onlineClients = append(onlineClients, t.Email)
|
|
|
dbClientTraffics[dbTraffic_index].LastOnline = now
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // Set onlineUsers
|
|
|
- p.SetOnlineClients(onlineClients)
|
|
|
-
|
|
|
err = tx.Save(dbClientTraffics).Error
|
|
|
if err != nil {
|
|
|
logger.Warning("AddClientTraffic update data ", err)
|
|
|
@@ -3764,6 +3761,19 @@ func (s *InboundService) GetClientsLastOnline() (map[string]int64, error) {
|
|
|
return result, nil
|
|
|
}
|
|
|
|
|
|
+func (s *InboundService) RefreshOnlineClientsFromMap(lastOnlineMap map[string]int64) {
|
|
|
+ now := time.Now().UnixMilli()
|
|
|
+ newOnlineClients := make([]string, 0, len(lastOnlineMap))
|
|
|
+ for email, lastOnline := range lastOnlineMap {
|
|
|
+ if now-lastOnline < onlineGracePeriodMs {
|
|
|
+ newOnlineClients = append(newOnlineClients, email)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if p != nil {
|
|
|
+ p.SetOnlineClients(newOnlineClients)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
func (s *InboundService) FilterAndSortClientEmails(emails []string) ([]string, []string, error) {
|
|
|
db := database.GetDB()
|
|
|
|