mirror of
https://github.com/nezhahq/nezha.git
synced 2025-01-22 12:48:14 -05:00
add fm api (#456)
This commit is contained in:
parent
fa9d02396b
commit
d086e98711
@ -62,6 +62,9 @@ func routers(r *gin.Engine) {
|
|||||||
auth.POST("/terminal", commonHandler(createTerminal))
|
auth.POST("/terminal", commonHandler(createTerminal))
|
||||||
auth.GET("/ws/terminal/:id", commonHandler(terminalStream))
|
auth.GET("/ws/terminal/:id", commonHandler(terminalStream))
|
||||||
|
|
||||||
|
auth.GET("/file", commonHandler(createFM))
|
||||||
|
auth.GET("/ws/file/:id", commonHandler(fmStream))
|
||||||
|
|
||||||
auth.GET("/user", commonHandler(listUser))
|
auth.GET("/user", commonHandler(listUser))
|
||||||
auth.POST("/user", commonHandler(createUser))
|
auth.POST("/user", commonHandler(createUser))
|
||||||
auth.POST("/batch-delete/user", commonHandler(batchDeleteUser))
|
auth.POST("/batch-delete/user", commonHandler(batchDeleteUser))
|
||||||
|
@ -102,7 +102,7 @@ func createDDNS(c *gin.Context) (uint64, error) {
|
|||||||
// @Description Edit DDNS profile
|
// @Description Edit DDNS profile
|
||||||
// @Tags auth required
|
// @Tags auth required
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @param id path string true "Profile ID"
|
// @param id path uint true "Profile ID"
|
||||||
// @param request body model.DDNSForm true "DDNS Request"
|
// @param request body model.DDNSForm true "DDNS Request"
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} model.CommonResponse[any]
|
// @Success 200 {object} model.CommonResponse[any]
|
||||||
|
99
cmd/dashboard/controller/fm.go
Normal file
99
cmd/dashboard/controller/fm.go
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
"github.com/hashicorp/go-uuid"
|
||||||
|
"github.com/naiba/nezha/model"
|
||||||
|
"github.com/naiba/nezha/pkg/utils"
|
||||||
|
"github.com/naiba/nezha/pkg/websocketx"
|
||||||
|
"github.com/naiba/nezha/proto"
|
||||||
|
"github.com/naiba/nezha/service/rpc"
|
||||||
|
"github.com/naiba/nezha/service/singleton"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Create FM session
|
||||||
|
// @Summary Create FM session
|
||||||
|
// @Description Create an "attached" FM. It is advised to only call this within a terminal session.
|
||||||
|
// @Tags auth required
|
||||||
|
// @Accept json
|
||||||
|
// @Param id path uint true "Server ID"
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} model.CreateFMResponse
|
||||||
|
// @Router /file [get]
|
||||||
|
func createFM(c *gin.Context) (*model.CreateFMResponse, error) {
|
||||||
|
idStr := c.Param("id")
|
||||||
|
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
streamId, err := uuid.GenerateUUID()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc.NezhaHandlerSingleton.CreateStream(streamId)
|
||||||
|
|
||||||
|
singleton.ServerLock.RLock()
|
||||||
|
server := singleton.ServerList[id]
|
||||||
|
singleton.ServerLock.RUnlock()
|
||||||
|
if server == nil || server.TaskStream == nil {
|
||||||
|
return nil, errors.New("server not found or not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
fmData, _ := utils.Json.Marshal(&model.TaskFM{
|
||||||
|
StreamID: streamId,
|
||||||
|
})
|
||||||
|
if err := server.TaskStream.Send(&proto.Task{
|
||||||
|
Type: model.TaskTypeFM,
|
||||||
|
Data: string(fmData),
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &model.CreateFMResponse{
|
||||||
|
SessionID: streamId,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start FM stream
|
||||||
|
// @Summary Start FM stream
|
||||||
|
// @Description Start FM stream
|
||||||
|
// @Tags auth required
|
||||||
|
// @Param id path string true "Stream UUID"
|
||||||
|
// @Router /ws/file/{id} [get]
|
||||||
|
func fmStream(c *gin.Context) (any, error) {
|
||||||
|
streamId := c.Param("id")
|
||||||
|
if _, err := rpc.NezhaHandlerSingleton.GetStream(streamId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rpc.NezhaHandlerSingleton.CloseStream(streamId)
|
||||||
|
|
||||||
|
wsConn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer wsConn.Close()
|
||||||
|
conn := websocketx.NewConn(wsConn)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
// PING 保活
|
||||||
|
for {
|
||||||
|
if err = conn.WriteMessage(websocket.PingMessage, []byte{}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
time.Sleep(time.Second * 10)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err = rpc.NezhaHandlerSingleton.UserConnected(streamId, conn); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, rpc.NezhaHandlerSingleton.StartStream(streamId, time.Second*10)
|
||||||
|
}
|
@ -110,7 +110,7 @@ func createNotificationGroup(c *gin.Context) (uint64, error) {
|
|||||||
// @Security BearerAuth
|
// @Security BearerAuth
|
||||||
// @Tags auth required
|
// @Tags auth required
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param id path string true "ID"
|
// @Param id path uint true "ID"
|
||||||
// @Param body body model.NotificationGroupForm true "NotificationGroupForm"
|
// @Param body body model.NotificationGroupForm true "NotificationGroupForm"
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} model.CommonResponse[any]
|
// @Success 200 {object} model.CommonResponse[any]
|
||||||
|
@ -107,7 +107,7 @@ func createServerGroup(c *gin.Context) (uint64, error) {
|
|||||||
// @Security BearerAuth
|
// @Security BearerAuth
|
||||||
// @Tags auth required
|
// @Tags auth required
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param id path string true "ID"
|
// @Param id path uint true "ID"
|
||||||
// @Param body body model.ServerGroupForm true "ServerGroupForm"
|
// @Param body body model.ServerGroupForm true "ServerGroupForm"
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} model.CommonResponse[any]
|
// @Success 200 {object} model.CommonResponse[any]
|
||||||
|
@ -65,8 +65,8 @@ func createTerminal(c *gin.Context) (*model.CreateTerminalResponse, error) {
|
|||||||
// @Summary Terminal stream
|
// @Summary Terminal stream
|
||||||
// @Description Terminal stream
|
// @Description Terminal stream
|
||||||
// @Tags auth required
|
// @Tags auth required
|
||||||
// @Param id path string true "Stream ID"
|
// @Param id path string true "Stream UUID"
|
||||||
// @Router /terminal/{id} [get]
|
// @Router /ws/terminal/{id} [get]
|
||||||
func terminalStream(c *gin.Context) (any, error) {
|
func terminalStream(c *gin.Context) (any, error) {
|
||||||
streamId := c.Param("id")
|
streamId := c.Param("id")
|
||||||
if _, err := rpc.NezhaHandlerSingleton.GetStream(streamId); err != nil {
|
if _, err := rpc.NezhaHandlerSingleton.GetStream(streamId); err != nil {
|
||||||
|
5
model/fm_api.go
Normal file
5
model/fm_api.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type CreateFMResponse struct {
|
||||||
|
SessionID string `json:"session_id,omitempty"`
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user