mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-04-20 05:52:24 +00:00
feature/9
9 / ClientOnlineIPs api
This commit is contained in:
parent
26abb907a0
commit
42d5dcb17e
6 changed files with 78 additions and 2 deletions
|
@ -12,6 +12,10 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ClientOnlineIPsResponse struct {
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
type InboundController struct {
|
||||
inboundService service.InboundService
|
||||
xrayService service.XrayService
|
||||
|
@ -30,6 +34,7 @@ func (a *InboundController) initRouter(g *gin.RouterGroup) {
|
|||
g.POST("/add", a.addInbound)
|
||||
g.POST("/del/:id", a.delInbound)
|
||||
g.POST("/update/:id", a.updateInbound)
|
||||
g.POST("/clientOnlineIps/:email", a.getClientOnlineIPs)
|
||||
g.POST("/clientIps/:email", a.getClientIps)
|
||||
g.POST("/clearClientIps/:email", a.clearClientIps)
|
||||
g.POST("/addClient", a.addInboundClient)
|
||||
|
@ -146,6 +151,21 @@ func (a *InboundController) updateInbound(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
func (a *InboundController) getClientOnlineIPs(c *gin.Context) {
|
||||
email := c.Param("email")
|
||||
|
||||
count, err := a.inboundService.GetClientOnlineIPs(email)
|
||||
res := &ClientOnlineIPsResponse{
|
||||
Count: count,
|
||||
}
|
||||
if err != nil {
|
||||
jsonObj(c, res, err)
|
||||
return
|
||||
}
|
||||
|
||||
jsonObj(c, res, nil)
|
||||
}
|
||||
|
||||
func (a *InboundController) getClientIps(c *gin.Context) {
|
||||
email := c.Param("email")
|
||||
|
||||
|
|
|
@ -46,8 +46,13 @@ func jsonMsgObj(c *gin.Context, msg string, obj interface{}, err error) {
|
|||
}
|
||||
} else {
|
||||
m.Success = false
|
||||
m.Msg = msg + " " + I18nWeb(c, "fail") + ": " + err.Error()
|
||||
logger.Warning(msg+" "+I18nWeb(c, "fail")+": ", err)
|
||||
if msg != "" {
|
||||
m.Msg = msg + " " + I18nWeb(c, "fail") + ": " + err.Error()
|
||||
logger.Warning(msg+" "+I18nWeb(c, "fail")+": ", err)
|
||||
} else {
|
||||
m.Msg = I18nWeb(c, "fail") + ": " + err.Error()
|
||||
logger.Warning(I18nWeb(c, "fail")+": ", err)
|
||||
}
|
||||
}
|
||||
c.JSON(http.StatusOK, m)
|
||||
}
|
||||
|
|
|
@ -1855,6 +1855,18 @@ func (s *InboundService) SearchClientTraffic(query string) (traffic *xray.Client
|
|||
return traffic, nil
|
||||
}
|
||||
|
||||
func (s *InboundService) GetClientOnlineIPs(email string) (int, error) {
|
||||
s.xrayApi.Init(p.GetAPIPort())
|
||||
defer s.xrayApi.Close()
|
||||
|
||||
count, err := s.xrayApi.GetClientOnlineIPs(email)
|
||||
if err != nil {
|
||||
logger.Debug("Failed to fetch Xray Client Online IPs:", err)
|
||||
return 0, err
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (s *InboundService) GetInboundClientIps(clientEmail string) (string, error) {
|
||||
db := database.GetDB()
|
||||
InboundClientIps := &model.InboundClientIps{}
|
||||
|
|
|
@ -61,6 +61,7 @@ type Status struct {
|
|||
State ProcessState `json:"state"`
|
||||
ErrorMsg string `json:"errorMsg"`
|
||||
Version string `json:"version"`
|
||||
ApiPort string `json:"apiPort"`
|
||||
} `json:"xray"`
|
||||
Uptime uint64 `json:"uptime"`
|
||||
Loads []float64 `json:"loads"`
|
||||
|
@ -239,6 +240,7 @@ func (s *ServerService) GetStatus(lastStatus *Status) *Status {
|
|||
status.Xray.ErrorMsg = s.xrayService.GetXrayResult()
|
||||
}
|
||||
status.Xray.Version = s.xrayService.GetXrayVersion()
|
||||
status.Xray.ApiPort = s.xrayService.GetXrayApiPort()
|
||||
var rtm runtime.MemStats
|
||||
runtime.ReadMemStats(&rtm)
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"sync"
|
||||
"strconv"
|
||||
|
||||
"x-ui/logger"
|
||||
"x-ui/xray"
|
||||
|
@ -56,6 +57,13 @@ func (s *XrayService) GetXrayVersion() string {
|
|||
return p.GetVersion()
|
||||
}
|
||||
|
||||
func (s *XrayService) GetXrayApiPort() string {
|
||||
if p == nil {
|
||||
return "Unknown"
|
||||
}
|
||||
return strconv.Itoa(p.GetAPIPort())
|
||||
}
|
||||
|
||||
func RemoveIndex(s []interface{}, index int) []interface{} {
|
||||
return append(s[:index], s[index+1:]...)
|
||||
}
|
||||
|
|
29
xray/api.go
29
xray/api.go
|
@ -204,6 +204,35 @@ func (x *XrayAPI) GetTraffic(reset bool) ([]*Traffic, []*ClientTraffic, error) {
|
|||
return mapToSlice(tagTrafficMap), mapToSlice(emailTrafficMap), nil
|
||||
}
|
||||
|
||||
func (x *XrayAPI) GetClientOnlineIPs(email string) (int, error) {
|
||||
if x.grpcClient == nil {
|
||||
return 0, common.NewError("xray api is not initialized")
|
||||
}
|
||||
|
||||
statName := "user>>>" + email + ">>>online"
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
|
||||
defer cancel()
|
||||
|
||||
if x.StatsServiceClient == nil {
|
||||
return 0, common.NewError("xray StatusServiceClient is not initialized")
|
||||
}
|
||||
|
||||
r := &statsService.GetStatsRequest{
|
||||
Name: statName,
|
||||
Reset_: false,
|
||||
}
|
||||
resp, err := (*x.StatsServiceClient).GetStatsOnline(ctx, r)
|
||||
if err != nil {
|
||||
logger.Debug("Failed to query Xray statsonline:", err)
|
||||
return 0, err
|
||||
}
|
||||
|
||||
count := resp.GetStat().Value
|
||||
|
||||
return int(count), nil
|
||||
}
|
||||
|
||||
func processTraffic(matches []string, value int64, trafficMap map[string]*Traffic) {
|
||||
isInbound := matches[1] == "inbound"
|
||||
tag := matches[2]
|
||||
|
|
Loading…
Reference in a new issue