195 lines
4.0 KiB
Go
195 lines
4.0 KiB
Go
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
|
|
}
|