This commit is contained in:
2024-12-23 18:34:46 +08:00
commit cbfcc91eec
24 changed files with 1702 additions and 0 deletions

194
httpserver/server.go Normal file
View File

@@ -0,0 +1,194 @@
package httpserver
import (
"DT/tcpserver"
"DT/ws"
"context"
"fmt"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"log"
"net/http"
)
// Server HTTP服务器结构
type Server struct {
tcpServer *tcpserver.Server
httpServer *http.Server
router *gin.Engine
hub *ws.Hub
}
// NewServer 创建一个新的HTTP服务器
func NewServer(addr string, tcpServer *tcpserver.Server) *Server {
router := gin.Default()
hub := ws.NewHub()
server := &Server{
tcpServer: tcpServer,
router: router,
httpServer: &http.Server{
Addr: addr,
Handler: router,
},
hub: hub,
}
// 启动 hub
go hub.Run()
// 注册路由
server.registerRoutes()
return server
}
// 添加请求结构体
type SendCommandRequest struct {
Imei string `json:"Imei" binding:"required"`
Command string `json:"command" binding:"required"`
}
// registerRoutes 方法
func (s *Server) registerRoutes() {
// 获取在线客户端列表
s.router.GET("/clients", s.handleGetClients)
// 添加发送命令的路由
s.router.POST("/clients_send", s.handleSendCommand)
// WebSocket 路由 - 使用查询参数获取 IMEI
s.router.GET("/ws/:imei", s.handleWebSocket)
}
// 处理发送命令的方法
func (s *Server) handleSendCommand(c *gin.Context) {
var req SendCommandRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"code": 400,
"msg": "invalid request: " + err.Error(),
})
return
}
// 查找目标客户端
clients := s.tcpServer.GetOnlineClients()
var targetClient *tcpserver.Client
found := false
for _, client := range clients {
if client["imei"] == req.Imei {
if clientObj, ok := s.tcpServer.GetClient(client["id"].(string)); ok {
targetClient = clientObj
found = true
break
}
}
}
if !found {
c.JSON(http.StatusNotFound, gin.H{
"code": 404,
"msg": "client not found",
})
return
}
// 发送命令
_, err := targetClient.Conn.Write(append([]byte(req.Command), '\r', '\n'))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"code": 500,
"msg": "failed to send command: " + err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"code": 200,
"msg": "success",
"data": gin.H{
"imei": req.Imei,
"command": req.Command,
},
})
}
// handleGetClients 处理获取客户端列表的请求
func (s *Server) handleGetClients(c *gin.Context) {
clients := s.tcpServer.GetOnlineClients()
c.JSON(http.StatusOK, gin.H{
"code": 200,
"msg": "success",
"data": gin.H{
"total": len(clients),
"clients": clients,
},
})
}
// 添加 WebSocket 处理函数
func (s *Server) handleWebSocket(c *gin.Context) {
imei := c.Param("imei")
//imei := c.Query("imei")
if imei == "" {
log.Printf("IMEI 参数为空")
c.String(http.StatusBadRequest, "IMEI parameter is required")
return
}
//devId, err := strconv.Atoi(deviceId)
//if err != nil {
// log.Printf("设备ID转换失败: %v", err)
// c.String(http.StatusBadRequest, "Invalid device ID")
// return
//}
log.Printf("WebSocket 连接请求: imei=%s", imei)
upgrader := websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
log.Printf("WebSocket 升级失败: %v", err)
return
}
client := &ws.Client{
Hub: s.hub,
Conn: conn,
Send: make(chan *ws.WsMessage, 256),
Imei: imei,
//DeviceId: devId,
}
log.Printf("WebSocket 客户端创建: imei=%s", imei)
client.Hub.Register <- client
go client.WritePump()
go client.ReadPump()
}
// Start 启动HTTP服务器
func (s *Server) Start() error {
return s.httpServer.ListenAndServe()
}
// Stop 优雅关闭HTTP服务器
func (s *Server) Stop(ctx context.Context) error {
fmt.Println("Stopping HTTP server...")
if err := s.httpServer.Shutdown(ctx); err != nil {
return fmt.Errorf("HTTP server forced to shutdown: %w", err)
}
fmt.Println("HTTP server stopped gracefully")
return nil
}
// GetHub 添加获取 Hub 的方法
func (s *Server) GetHub() *ws.Hub {
return s.hub
}