feat: add support for starting plugin rules with remote port configuration
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 28s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 1m7s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 50s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 2m33s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 1m2s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 2m26s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 58s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 2m32s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 2m9s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 1m30s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 3m6s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 2m30s
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 28s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 1m7s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 50s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 2m33s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 1m2s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 2m26s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 58s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 2m32s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 2m9s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 1m30s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 3m6s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 2m30s
This commit is contained in:
@@ -47,6 +47,8 @@ type ServerInterface interface {
|
|||||||
StopClientLogStream(sessionID string)
|
StopClientLogStream(sessionID string)
|
||||||
// 插件状态查询
|
// 插件状态查询
|
||||||
GetClientPluginStatus(clientID string) ([]protocol.PluginStatusEntry, error)
|
GetClientPluginStatus(clientID string) ([]protocol.PluginStatusEntry, error)
|
||||||
|
// 插件规则管理
|
||||||
|
StartPluginRule(clientID string, rule protocol.ProxyRule) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigField 配置字段
|
// ConfigField 配置字段
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gotunnel/internal/server/db"
|
"github.com/gotunnel/internal/server/db"
|
||||||
// removed router import
|
|
||||||
"github.com/gotunnel/internal/server/router/dto"
|
"github.com/gotunnel/internal/server/router/dto"
|
||||||
|
"github.com/gotunnel/pkg/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StoreHandler 插件商店处理器
|
// StoreHandler 插件商店处理器
|
||||||
@@ -192,9 +192,26 @@ func (h *StoreHandler) Install(c *gin.Context) {
|
|||||||
h.app.GetClientStore().UpdateClient(dbClient)
|
h.app.GetClientStore().UpdateClient(dbClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 启动服务端监听器(让外部用户可以通过 RemotePort 访问插件)
|
||||||
|
if req.RemotePort > 0 {
|
||||||
|
pluginRule := protocol.ProxyRule{
|
||||||
|
Name: req.PluginName,
|
||||||
|
Type: req.PluginName, // 使用插件名作为类型,让 isClientPlugin 识别
|
||||||
|
RemotePort: req.RemotePort,
|
||||||
|
Enabled: boolPtr(true),
|
||||||
|
}
|
||||||
|
// 启动监听器(忽略错误,可能端口已被占用)
|
||||||
|
h.app.GetServer().StartPluginRule(req.ClientID, pluginRule)
|
||||||
|
}
|
||||||
|
|
||||||
Success(c, gin.H{
|
Success(c, gin.H{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"plugin": req.PluginName,
|
"plugin": req.PluginName,
|
||||||
"client": req.ClientID,
|
"client": req.ClientID,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// boolPtr 返回 bool 值的指针
|
||||||
|
func boolPtr(b bool) *bool {
|
||||||
|
return &b
|
||||||
|
}
|
||||||
|
|||||||
@@ -1227,6 +1227,15 @@ func (s *Server) pushClientInstalledPlugins(cs *ClientSession, alreadyPushed map
|
|||||||
|
|
||||||
if err := s.InstallJSPluginToClient(cs.ID, req); err != nil {
|
if err := s.InstallJSPluginToClient(cs.ID, req); err != nil {
|
||||||
log.Printf("[Server] Failed to restore plugin %s: %v", cp.Name, err)
|
log.Printf("[Server] Failed to restore plugin %s: %v", cp.Name, err)
|
||||||
|
} else if cp.RemotePort > 0 {
|
||||||
|
// 安装成功后启动服务端监听器
|
||||||
|
pluginRule := protocol.ProxyRule{
|
||||||
|
Name: cp.Name,
|
||||||
|
Type: cp.Name,
|
||||||
|
RemotePort: cp.RemotePort,
|
||||||
|
Enabled: boolPtr(true),
|
||||||
|
}
|
||||||
|
s.startClientPluginListener(cs, pluginRule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1342,6 +1351,30 @@ func (s *Server) sendClientPluginStop(session *yamux.Session, pluginName, ruleNa
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StartPluginRule 为客户端插件启动服务端监听器
|
||||||
|
func (s *Server) StartPluginRule(clientID string, rule protocol.ProxyRule) error {
|
||||||
|
s.mu.RLock()
|
||||||
|
cs, ok := s.clients[clientID]
|
||||||
|
s.mu.RUnlock()
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("client %s not found or not online", clientID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查端口是否已被占用
|
||||||
|
cs.mu.Lock()
|
||||||
|
_, exists := cs.Listeners[rule.RemotePort]
|
||||||
|
cs.mu.Unlock()
|
||||||
|
if exists {
|
||||||
|
// 端口已在监听,无需重复启动
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动插件监听器
|
||||||
|
s.startClientPluginListener(cs, rule)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// RestartClientPlugin 重启客户端 JS 插件
|
// RestartClientPlugin 重启客户端 JS 插件
|
||||||
func (s *Server) RestartClientPlugin(clientID, pluginName, ruleName string) error {
|
func (s *Server) RestartClientPlugin(clientID, pluginName, ruleName string) error {
|
||||||
s.mu.RLock()
|
s.mu.RLock()
|
||||||
@@ -1612,3 +1645,8 @@ func (s *Server) StopClientLogStream(sessionID string) {
|
|||||||
|
|
||||||
s.logSessions.RemoveSession(sessionID)
|
s.logSessions.RemoveSession(sessionID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// boolPtr 返回 bool 值的指针
|
||||||
|
func boolPtr(b bool) *bool {
|
||||||
|
return &b
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user