add process share

This commit is contained in:
akrike
2025-06-01 12:41:11 +08:00
parent be6bbef98c
commit d533d345ec
6 changed files with 105 additions and 1 deletions

View File

@@ -1,9 +1,13 @@
package api
import (
"time"
"github.com/google/uuid"
"github.com/lzh-1625/go_process_manager/internal/app/logic"
"github.com/lzh-1625/go_process_manager/internal/app/model"
"github.com/lzh-1625/go_process_manager/internal/app/repository"
"github.com/lzh-1625/go_process_manager/utils"
"github.com/gin-gonic/gin"
)
@@ -107,3 +111,14 @@ func (p *procApi) ProcessControl(ctx *gin.Context) {
proc.ProcessControl(user)
rOk(ctx, "Operation successful!", nil)
}
func (p *procApi) ProcessCreateShare(ctx *gin.Context) {
req := bind[model.ProcessShare](ctx)
err := repository.WsShare.AddShareData(model.WsShare{
ExpireTime: time.Now().Add(time.Minute * time.Duration(req.Minute)),
Write: req.Write,
Token: utils.UnwarpIgnore(uuid.NewRandom()).String(),
})
errCheck(ctx, err != nil, err)
rOk(ctx, "Operation successful!", nil)
}

View File

@@ -2,6 +2,7 @@ package api
import (
"context"
"strconv"
"sync"
"time"
@@ -9,6 +10,7 @@ import (
"github.com/lzh-1625/go_process_manager/internal/app/constants"
"github.com/lzh-1625/go_process_manager/internal/app/logic"
"github.com/lzh-1625/go_process_manager/internal/app/middle"
"github.com/lzh-1625/go_process_manager/internal/app/repository"
"github.com/lzh-1625/go_process_manager/log"
"github.com/lzh-1625/go_process_manager/utils"
@@ -92,6 +94,53 @@ func (w *wsApi) WebsocketHandle(ctx *gin.Context) {
conn.Close()
}
func (w *wsApi) WebsocketShareHandle(ctx *gin.Context) {
token := getQueryString(ctx, "token")
data, err := repository.WsShare.GetWsShareDataByToken(token)
errCheck(ctx, err != nil, "Operation failed!")
errCheck(ctx, data.ExpireTime.Unix() <= time.Now().Unix(), "Share expired!")
proc, err := logic.ProcessCtlLogic.GetProcess(data.Pid)
errCheck(ctx, err != nil, "Operation failed!")
gusetName := "guest-" + strconv.Itoa(data.Id) // 构造访客用户名
errCheck(ctx, proc.HasWsConn(gusetName), "A connection already exists; unable to establish a new one!")
errCheck(ctx, proc.State.State != 1, "The process is currently running.")
errCheck(ctx, !proc.VerifyControl(), "Insufficient permissions; please check your access rights!")
conn, err := upgrader.Upgrade(ctx.Writer, ctx.Request, nil)
errCheck(ctx, err != nil, "WebSocket connection upgrade failed!")
log.Logger.Infow("ws连接成功")
proc.SetTerminalSize(utils.GetIntByString(ctx.Query("cols")), utils.GetIntByString(ctx.Query("rows")))
wsCtx, cancel := context.WithCancel(context.Background())
wci := &WsConnetInstance{
WsConnect: conn,
CancelFunc: cancel,
wsLock: sync.Mutex{},
}
proc.ReadCache(wci)
w.startWsConnect(wci, cancel, proc, data.Write)
proc.AddConn(gusetName, wci)
defer middle.ProcessWaitCond.Trigger()
defer proc.DeleteConn(gusetName)
conn.SetCloseHandler(func(_ int, _ string) error {
middle.ProcessWaitCond.Trigger()
cancel()
return nil
})
middle.ProcessWaitCond.Trigger()
select {
case <-proc.StopChan:
log.Logger.Infow("ws连接断开", "操作类型", "进程已停止强制断开ws连接")
case <-time.After(time.Minute * time.Duration(config.CF.TerminalConnectTimeout)):
log.Logger.Infow("ws连接断开", "操作类型", "连接时间超过最大时长限制")
case <-wsCtx.Done():
log.Logger.Infow("ws连接断开", "操作类型", "tcp连接建立已被关闭")
case <-time.After(time.Until(data.ExpireTime)):
log.Logger.Infow("ws连接断开", "操作类型", "分享时间已结束")
}
conn.Close()
}
func (w *wsApi) startWsConnect(wci *WsConnetInstance, cancel context.CancelFunc, proc logic.Process, write bool) {
log.Logger.Debugw("ws读取线程已启动")
go func() {

View File

@@ -20,3 +20,9 @@ type Process struct {
func (*Process) TableName() string {
return "process"
}
type ProcessShare struct {
Minute int `json:"minute"`
Pid int `json:"pid"`
Write bool `json:"write"`
}

View File

@@ -0,0 +1,13 @@
package model
import (
"time"
)
type WsShare struct {
Id int `gorm:"primaryKey;autoIncrement;column:id" json:"id"`
Pid int `gorm:"column:pid" json:"pid"`
Write bool `gorm:"column:write" json:"write"`
ExpireTime time.Time `gorm:"column:expire_time" json:"expireTime"`
Token string `gorm:"column:token" json:"token"`
}

View File

@@ -0,0 +1,16 @@
package repository
import "github.com/lzh-1625/go_process_manager/internal/app/model"
type wsShare struct{}
var WsShare = new(wsShare)
func (p *wsShare) GetWsShareDataByToken(token string) (data model.WsShare, err error) {
err = db.Model(&model.WsShare{}).Where("token = ?", token).First(&data).Error
return
}
func (p *wsShare) AddShareData(data model.WsShare) error {
return db.Save(data).Error
}

View File

@@ -56,7 +56,11 @@ func routePathInit(r *gin.Engine) {
apiGroup.Use(middle.PanicMiddle())
// apiGroup.Use(middle.DemoMiddle())
{
apiGroup.GET("/ws", middle.OprPermission(constants.OPERATION_TERMINAL), api.WsApi.WebsocketHandle)
wsGroup := apiGroup.Group("/ws")
{
wsGroup.GET("", middle.OprPermission(constants.OPERATION_TERMINAL), api.WsApi.WebsocketHandle)
wsGroup.GET("/share", api.WsApi.WebsocketShareHandle)
}
processGroup := apiGroup.Group("/process")
{
@@ -66,6 +70,7 @@ func routePathInit(r *gin.Engine) {
processGroup.PUT("", middle.OprPermission(constants.OPERATION_START), api.ProcApi.StartProcess)
processGroup.PUT("/all", api.ProcApi.StartAllProcess)
processGroup.DELETE("/all", api.ProcApi.KillAllProcess)
processGroup.POST("/share", middle.RolePermission(constants.ROLE_ADMIN), api.ProcApi.ProcessCreateShare)
processGroup.GET("/control", middle.RolePermission(constants.ROLE_ROOT), middle.ProcessWaitCond.WaitTriggerMiddel, api.ProcApi.ProcessControl)
proConfigGroup := processGroup.Group("/config")