mirror of
https://github.com/lzh-1625/go_process_manager.git
synced 2025-10-05 16:06:51 +08:00
add process share
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
@@ -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() {
|
||||
|
@@ -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"`
|
||||
}
|
||||
|
13
internal/app/model/ws_share.go
Normal file
13
internal/app/model/ws_share.go
Normal 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"`
|
||||
}
|
16
internal/app/repository/ws_share.go
Normal file
16
internal/app/repository/ws_share.go
Normal 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
|
||||
}
|
@@ -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")
|
||||
|
Reference in New Issue
Block a user