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
|
package api
|
||||||
|
|
||||||
import (
|
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/logic"
|
||||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
"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/internal/app/repository"
|
||||||
|
"github.com/lzh-1625/go_process_manager/utils"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
@@ -107,3 +111,14 @@ func (p *procApi) ProcessControl(ctx *gin.Context) {
|
|||||||
proc.ProcessControl(user)
|
proc.ProcessControl(user)
|
||||||
rOk(ctx, "Operation successful!", nil)
|
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"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/constants"
|
||||||
"github.com/lzh-1625/go_process_manager/internal/app/logic"
|
"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/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/log"
|
||||||
"github.com/lzh-1625/go_process_manager/utils"
|
"github.com/lzh-1625/go_process_manager/utils"
|
||||||
|
|
||||||
@@ -92,6 +94,53 @@ func (w *wsApi) WebsocketHandle(ctx *gin.Context) {
|
|||||||
conn.Close()
|
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) {
|
func (w *wsApi) startWsConnect(wci *WsConnetInstance, cancel context.CancelFunc, proc logic.Process, write bool) {
|
||||||
log.Logger.Debugw("ws读取线程已启动")
|
log.Logger.Debugw("ws读取线程已启动")
|
||||||
go func() {
|
go func() {
|
||||||
|
@@ -20,3 +20,9 @@ type Process struct {
|
|||||||
func (*Process) TableName() string {
|
func (*Process) TableName() string {
|
||||||
return "process"
|
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.PanicMiddle())
|
||||||
// apiGroup.Use(middle.DemoMiddle())
|
// 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")
|
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("", middle.OprPermission(constants.OPERATION_START), api.ProcApi.StartProcess)
|
||||||
processGroup.PUT("/all", api.ProcApi.StartAllProcess)
|
processGroup.PUT("/all", api.ProcApi.StartAllProcess)
|
||||||
processGroup.DELETE("/all", api.ProcApi.KillAllProcess)
|
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)
|
processGroup.GET("/control", middle.RolePermission(constants.ROLE_ROOT), middle.ProcessWaitCond.WaitTriggerMiddel, api.ProcApi.ProcessControl)
|
||||||
|
|
||||||
proConfigGroup := processGroup.Group("/config")
|
proConfigGroup := processGroup.Group("/config")
|
||||||
|
Reference in New Issue
Block a user