feat(client, server): add client name handling and machine ID retrieval
Some checks failed
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Has been cancelled
Build Multi-Platform Binaries / build-frontend (push) Has been cancelled
Some checks failed
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Has been cancelled
Build Multi-Platform Binaries / build-frontend (push) Has been cancelled
This commit is contained in:
@@ -115,7 +115,7 @@ func (h *ClientHandler) Get(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
online, lastPing, remoteAddr, clientOS, clientArch, clientVersion := h.app.GetServer().GetClientStatus(clientID)
|
||||
online, lastPing, remoteAddr, clientName, clientOS, clientArch, clientVersion := h.app.GetServer().GetClientStatus(clientID)
|
||||
|
||||
// 复制插件列表
|
||||
plugins := make([]db.ClientPlugin, len(client.Plugins))
|
||||
@@ -145,9 +145,15 @@ func (h *ClientHandler) Get(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// 如果客户端在线且有名称,优先使用在线名称
|
||||
nickname := client.Nickname
|
||||
if online && clientName != "" && nickname == "" {
|
||||
nickname = clientName
|
||||
}
|
||||
|
||||
resp := dto.ClientResponse{
|
||||
ID: client.ID,
|
||||
Nickname: client.Nickname,
|
||||
Nickname: nickname,
|
||||
Rules: client.Rules,
|
||||
Plugins: plugins,
|
||||
Online: online,
|
||||
@@ -242,8 +248,7 @@ func (h *ClientHandler) Delete(c *gin.Context) {
|
||||
func (h *ClientHandler) PushConfig(c *gin.Context) {
|
||||
clientID := c.Param("id")
|
||||
|
||||
online, _, _, _, _, _ := h.app.GetServer().GetClientStatus(clientID)
|
||||
if !online {
|
||||
if !h.app.GetServer().IsClientOnline(clientID) {
|
||||
ClientNotOnline(c)
|
||||
return
|
||||
}
|
||||
@@ -311,8 +316,7 @@ func (h *ClientHandler) Restart(c *gin.Context) {
|
||||
func (h *ClientHandler) InstallPlugins(c *gin.Context) {
|
||||
clientID := c.Param("id")
|
||||
|
||||
online, _, _, _, _, _ := h.app.GetServer().GetClientStatus(clientID)
|
||||
if !online {
|
||||
if !h.app.GetServer().IsClientOnline(clientID) {
|
||||
ClientNotOnline(c)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -19,11 +19,13 @@ type AppInterface interface {
|
||||
|
||||
// ServerInterface 服务端接口
|
||||
type ServerInterface interface {
|
||||
GetClientStatus(clientID string) (online bool, lastPing, remoteAddr, clientOS, clientArch, clientVersion string)
|
||||
IsClientOnline(clientID string) bool
|
||||
GetClientStatus(clientID string) (online bool, lastPing, remoteAddr, clientName, clientOS, clientArch, clientVersion string)
|
||||
GetAllClientStatus() map[string]struct {
|
||||
Online bool
|
||||
LastPing string
|
||||
RemoteAddr string
|
||||
Name string
|
||||
OS string
|
||||
Arch string
|
||||
Version string
|
||||
|
||||
@@ -177,8 +177,7 @@ func (h *JSPluginHandler) PushToClient(c *gin.Context) {
|
||||
c.ShouldBindJSON(&pushReq) // 忽略错误,允许空请求体
|
||||
|
||||
// 检查客户端是否在线
|
||||
online, _, _, _, _, _ := h.app.GetServer().GetClientStatus(clientID)
|
||||
if !online {
|
||||
if !h.app.GetServer().IsClientOnline(clientID) {
|
||||
ClientNotOnline(c)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -35,8 +35,7 @@ func (h *LogHandler) StreamLogs(c *gin.Context) {
|
||||
clientID := c.Param("id")
|
||||
|
||||
// 检查客户端是否在线
|
||||
online, _, _, _, _, _ := h.app.GetServer().GetClientStatus(clientID)
|
||||
if !online {
|
||||
if !h.app.GetServer().IsClientOnline(clientID) {
|
||||
c.JSON(400, gin.H{"code": 400, "message": "client not online"})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -371,8 +371,7 @@ func (h *PluginHandler) UpdateClientConfig(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 如果客户端在线,同步配置
|
||||
online, _, _, _, _, _ := h.app.GetServer().GetClientStatus(clientID)
|
||||
if online {
|
||||
if h.app.GetServer().IsClientOnline(clientID) {
|
||||
if err := h.app.GetServer().SyncPluginConfigToClient(clientID, pluginName, req.Config); err != nil {
|
||||
PartialSuccess(c, gin.H{"status": "partial", "port_changed": portChanged}, "config saved but sync failed: "+err.Error())
|
||||
return
|
||||
|
||||
@@ -45,8 +45,7 @@ func (h *PluginAPIHandler) ProxyRequest(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 检查客户端是否在线
|
||||
online, _, _, _, _, _ := h.app.GetServer().GetClientStatus(clientID)
|
||||
if !online {
|
||||
if !h.app.GetServer().IsClientOnline(clientID) {
|
||||
ClientNotOnline(c)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -82,8 +82,7 @@ func (h *StoreHandler) Install(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 检查客户端是否在线
|
||||
online, _, _, _, _, _ := h.app.GetServer().GetClientStatus(req.ClientID)
|
||||
if !online {
|
||||
if !h.app.GetServer().IsClientOnline(req.ClientID) {
|
||||
ClientNotOnline(c)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ type JSPluginEntry struct {
|
||||
// ClientSession 客户端会话
|
||||
type ClientSession struct {
|
||||
ID string
|
||||
Name string // 客户端名称(主机名)
|
||||
RemoteAddr string // 客户端 IP 地址
|
||||
OS string // 客户端操作系统
|
||||
Arch string // 客户端架构
|
||||
@@ -269,13 +270,21 @@ func (s *Server) handleConnection(conn net.Conn) {
|
||||
// 检查客户端是否存在,不存在则自动创建
|
||||
exists, err := s.clientStore.ClientExists(clientID)
|
||||
if err != nil || !exists {
|
||||
newClient := &db.Client{ID: clientID, Rules: []protocol.ProxyRule{}}
|
||||
newClient := &db.Client{ID: clientID, Nickname: authReq.Name, Rules: []protocol.ProxyRule{}}
|
||||
if err := s.clientStore.CreateClient(newClient); err != nil {
|
||||
log.Printf("[Server] Create client error: %v", err)
|
||||
s.sendAuthResponse(conn, false, "failed to create client", "")
|
||||
return
|
||||
}
|
||||
log.Printf("[Server] New client registered: %s", clientID)
|
||||
log.Printf("[Server] New client registered: %s (%s)", clientID, authReq.Name)
|
||||
} else if authReq.Name != "" {
|
||||
// 客户端已存在,更新名称(如果提供了新名称)
|
||||
if client, err := s.clientStore.GetClient(clientID); err == nil {
|
||||
if client.Nickname == "" || client.Nickname != authReq.Name {
|
||||
client.Nickname = authReq.Name
|
||||
s.clientStore.UpdateClient(client)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rules, _ := s.clientStore.GetClientRules(clientID)
|
||||
@@ -290,11 +299,11 @@ func (s *Server) handleConnection(conn net.Conn) {
|
||||
}
|
||||
|
||||
security.LogAuthSuccess(clientIP, clientID)
|
||||
s.setupClientSession(conn, clientID, authReq.OS, authReq.Arch, authReq.Version, rules)
|
||||
s.setupClientSession(conn, clientID, authReq.Name, authReq.OS, authReq.Arch, authReq.Version, rules)
|
||||
}
|
||||
|
||||
// setupClientSession 建立客户端会话
|
||||
func (s *Server) setupClientSession(conn net.Conn, clientID, clientOS, clientArch, clientVersion string, rules []protocol.ProxyRule) {
|
||||
func (s *Server) setupClientSession(conn net.Conn, clientID, clientName, clientOS, clientArch, clientVersion string, rules []protocol.ProxyRule) {
|
||||
session, err := yamux.Server(conn, nil)
|
||||
if err != nil {
|
||||
log.Printf("[Server] Yamux error: %v", err)
|
||||
@@ -309,6 +318,7 @@ func (s *Server) setupClientSession(conn net.Conn, clientID, clientOS, clientArc
|
||||
|
||||
cs := &ClientSession{
|
||||
ID: clientID,
|
||||
Name: clientName,
|
||||
RemoteAddr: remoteAddr,
|
||||
OS: clientOS,
|
||||
Arch: clientArch,
|
||||
@@ -586,16 +596,24 @@ func (s *Server) sendHeartbeat(cs *ClientSession) bool {
|
||||
}
|
||||
|
||||
// GetClientStatus 获取客户端状态
|
||||
func (s *Server) GetClientStatus(clientID string) (online bool, lastPing, remoteAddr, clientOS, clientArch, clientVersion string) {
|
||||
func (s *Server) GetClientStatus(clientID string) (online bool, lastPing, remoteAddr, clientName, clientOS, clientArch, clientVersion string) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
if cs, ok := s.clients[clientID]; ok {
|
||||
cs.mu.Lock()
|
||||
defer cs.mu.Unlock()
|
||||
return true, cs.LastPing.Format(time.RFC3339), cs.RemoteAddr, cs.OS, cs.Arch, cs.Version
|
||||
return true, cs.LastPing.Format(time.RFC3339), cs.RemoteAddr, cs.Name, cs.OS, cs.Arch, cs.Version
|
||||
}
|
||||
return false, "", "", "", "", ""
|
||||
return false, "", "", "", "", "", ""
|
||||
}
|
||||
|
||||
// IsClientOnline 检查客户端是否在线
|
||||
func (s *Server) IsClientOnline(clientID string) bool {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
_, ok := s.clients[clientID]
|
||||
return ok
|
||||
}
|
||||
|
||||
// GetClientPluginStatus 获取客户端插件运行状态
|
||||
@@ -646,6 +664,7 @@ func (s *Server) GetAllClientStatus() map[string]struct {
|
||||
Online bool
|
||||
LastPing string
|
||||
RemoteAddr string
|
||||
Name string
|
||||
OS string
|
||||
Arch string
|
||||
Version string
|
||||
@@ -662,6 +681,7 @@ func (s *Server) GetAllClientStatus() map[string]struct {
|
||||
Online bool
|
||||
LastPing string
|
||||
RemoteAddr string
|
||||
Name string
|
||||
OS string
|
||||
Arch string
|
||||
Version string
|
||||
@@ -673,6 +693,7 @@ func (s *Server) GetAllClientStatus() map[string]struct {
|
||||
Online bool
|
||||
LastPing string
|
||||
RemoteAddr string
|
||||
Name string
|
||||
OS string
|
||||
Arch string
|
||||
Version string
|
||||
@@ -680,6 +701,7 @@ func (s *Server) GetAllClientStatus() map[string]struct {
|
||||
Online: true,
|
||||
LastPing: cs.LastPing.Format(time.RFC3339),
|
||||
RemoteAddr: cs.RemoteAddr,
|
||||
Name: cs.Name,
|
||||
OS: cs.OS,
|
||||
Arch: cs.Arch,
|
||||
Version: cs.Version,
|
||||
|
||||
Reference in New Issue
Block a user