| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- package controllers
- import (
- "encoding/json"
- "fmt"
- "time"
- "github.com/gofiber/websocket/v2"
- "github.com/google/uuid"
- "go.uber.org/zap"
- )
- type WsHandler func(messageType int, p []byte) bool
- type Client struct {
- ID string
- Conn *websocket.Conn
- }
- type MessageBody struct {
- Type string
- Data string
- }
- var clients = make(map[string]*Client)
- var handlers = make([]WsHandler, 0)
- func GlobalWebSocket(c *websocket.Conn) {
- sid := c.Cookies("sid")
- if sid == "" {
- sid = uuid.New().String()
- }
- client := &Client{ID: sid, Conn: c}
- clients[sid] = client
- defer func() {
- delete(clients, sid)
- c.Close()
- }()
- fmt.Println("Client connected:", sid)
- // 60 秒未收到任何 Pong/消息就判定断线
- c.SetReadDeadline(time.Now().Add(60 * time.Second))
- c.SetPongHandler(func(appData string) error {
- fmt.Println("📡 收到 pong 响应")
- c.SetReadDeadline(time.Now().Add(60 * time.Second))
- return nil
- })
- // 启动心跳 goroutine
- go func() {
- ticker := time.NewTicker(30 * time.Second)
- defer ticker.Stop()
- for range ticker.C {
- if err := c.WriteMessage(websocket.PingMessage, []byte("ping")); err != nil {
- fmt.Println("❌ 发送 ping 失败,关闭连接:", err)
- c.Close()
- return
- }
- fmt.Println("🟢 发送 ping")
- }
- }()
- for {
- // 读取消息
- msgType, msg, err := c.ReadMessage()
- if err != nil {
- zap.L().Error("GlobalWebSocket read err", zap.String("err", err.Error()))
- break
- }
- fmt.Printf("[%s] recv: %s\n", sid, string(msg))
- // 处理消息
- for _, handler := range handlers {
- ok := handler(msgType, msg)
- if ok {
- break
- }
- }
- }
- }
- func sendGlobalWebSocketMessage(body MessageBody) {
- for _, client := range clients {
- if client == nil {
- continue
- }
- payload, err := json.Marshal(body)
- if err != nil {
- zap.L().Error("json序列化失败", zap.String("err", err.Error()))
- continue
- }
- client.Conn.WriteMessage(websocket.TextMessage, []byte(payload))
- }
- }
- func RegisterGlobalWebSocketHandle(f WsHandler) {
- handlers = append(handlers, f)
- }
- // 以下实现发送各种消息的接口
|