Skip to content

Commit ad468e4

Browse files
authored
API: Add GetAllOnlineUsers RPC to StatsService for retrieving online users (#5080)
1 parent 6738ecf commit ad468e4

File tree

8 files changed

+371
-225
lines changed

8 files changed

+371
-225
lines changed

app/stats/command/command.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ func (s *statsServer) GetStatsOnlineIpList(ctx context.Context, request *GetStat
8080
}, nil
8181
}
8282

83+
func (s *statsServer) GetAllOnlineUsers(ctx context.Context, request *GetAllOnlineUsersRequest) (*GetAllOnlineUsersResponse, error) {
84+
return &GetAllOnlineUsersResponse{
85+
Users: s.stats.GetAllOnlineUsers(),
86+
}, nil
87+
}
88+
8389
func (s *statsServer) QueryStats(ctx context.Context, request *QueryStatsRequest) (*QueryStatsResponse, error) {
8490
matcher, err := strmatcher.Substr.New(request.Pattern)
8591
if err != nil {

app/stats/command/command.pb.go

Lines changed: 250 additions & 222 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/stats/command/command.proto

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,19 @@ message GetStatsOnlineIpListResponse {
5151
map<string, int64> ips = 2;
5252
}
5353

54+
message GetAllOnlineUsersRequest {}
55+
56+
message GetAllOnlineUsersResponse {
57+
repeated string users = 1;
58+
}
59+
5460
service StatsService {
5561
rpc GetStats(GetStatsRequest) returns (GetStatsResponse) {}
5662
rpc GetStatsOnline(GetStatsRequest) returns (GetStatsResponse) {}
5763
rpc QueryStats(QueryStatsRequest) returns (QueryStatsResponse) {}
5864
rpc GetSysStats(SysStatsRequest) returns (SysStatsResponse) {}
5965
rpc GetStatsOnlineIpList(GetStatsRequest) returns (GetStatsOnlineIpListResponse) {}
66+
rpc GetAllOnlineUsers(GetAllOnlineUsersRequest) returns (GetAllOnlineUsersResponse) {}
6067
}
6168

6269
message Config {}

app/stats/command/command_grpc.pb.go

Lines changed: 41 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/stats/stats.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,21 @@ func (m *Manager) GetChannel(name string) stats.Channel {
161161
return nil
162162
}
163163

164+
// GetAllOnlineUsers implements stats.Manager.
165+
func (m *Manager) GetAllOnlineUsers() []string {
166+
m.access.Lock()
167+
defer m.access.Unlock()
168+
169+
usersOnline := make([]string, 0, len(m.onlineMap))
170+
for user, onlineMap := range m.onlineMap {
171+
if len(onlineMap.IpTimeMap()) > 0 {
172+
usersOnline = append(usersOnline, user)
173+
}
174+
}
175+
176+
return usersOnline
177+
}
178+
164179
// Start implements common.Runnable.
165180
func (m *Manager) Start() error {
166181
m.access.Lock()

features/stats/stats.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ type Manager interface {
9898
UnregisterChannel(string) error
9999
// GetChannel returns a channel by its identifier.
100100
GetChannel(string) Channel
101+
102+
// GetAllOnlineUsers returns all online users from all OnlineMaps.
103+
GetAllOnlineUsers() []string
101104
}
102105

103106
// GetOrRegisterCounter tries to get the StatCounter first. If not exist, it then tries to create a new counter.
@@ -190,6 +193,11 @@ func (NoopManager) GetChannel(string) Channel {
190193
return nil
191194
}
192195

196+
// GetAllOnlineUsers implements Manager.
197+
func (NoopManager) GetAllOnlineUsers() []string {
198+
return nil
199+
}
200+
193201
// Start implements common.Runnable.
194202
func (NoopManager) Start() error { return nil }
195203

main/commands/all/api/api.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ var CmdAPI = &base.Command{
3232
cmdSourceIpBlock,
3333
cmdOnlineStats,
3434
cmdOnlineStatsIpList,
35+
cmdGetAllOnlineUsers,
3536
},
3637
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package api
2+
3+
import (
4+
statsService "github.com/xtls/xray-core/app/stats/command"
5+
"github.com/xtls/xray-core/main/commands/base"
6+
)
7+
8+
var cmdGetAllOnlineUsers = &base.Command{
9+
CustomFlags: true,
10+
UsageLine: "{{.Exec}} api statsgetallonlineusers [--server=127.0.0.1:8080]",
11+
Short: "Retrieve array of all online users",
12+
Long: `
13+
Retrieve array of all online users.
14+
15+
Arguments:
16+
17+
-s, -server <server:port>
18+
The API server address. Default 127.0.0.1:8080
19+
20+
-t, -timeout <seconds>
21+
Timeout in seconds for calling API. Default 3
22+
23+
Example:
24+
25+
{{.Exec}} {{.LongName}} --server=127.0.0.1:8080"
26+
`,
27+
Run: executeGetAllOnlineUsers,
28+
}
29+
30+
func executeGetAllOnlineUsers(cmd *base.Command, args []string) {
31+
setSharedFlags(cmd)
32+
cmd.Flag.Parse(args)
33+
conn, ctx, close := dialAPIServer()
34+
defer close()
35+
36+
client := statsService.NewStatsServiceClient(conn)
37+
r := &statsService.GetAllOnlineUsersRequest{}
38+
resp, err := client.GetAllOnlineUsers(ctx, r)
39+
if err != nil {
40+
base.Fatalf("failed to get stats: %s", err)
41+
}
42+
showJSONResponse(resp)
43+
}

0 commit comments

Comments
 (0)