package ws import ( "crypto/rand" "encoding/hex" "net/http" "strings" "time" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" "go.uber.org/zap" ) type Controller struct { hub *Hub upgrader websocket.Upgrader } func NewController(hub *Hub) *Controller { return &Controller{ hub: hub, upgrader: websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, }, } } // Connect 升级 HTTP 连接并加入指定房间。 // 浏览器连接示例:new WebSocket("ws://localhost:8080/api/ws?room=lobby&client_id=demo") func (c *Controller) Connect(ctx *gin.Context) { room := strings.TrimSpace(ctx.DefaultQuery("room", "lobby")) clientID := strings.TrimSpace(ctx.Query("client_id")) if room == "" || len(room) > 64 || len(clientID) > 64 { ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "room 或 client_id 不合法", "data": nil}) return } if clientID == "" { clientID = randomClientID() } conn, err := c.upgrader.Upgrade(ctx.Writer, ctx.Request, nil) if err != nil { zap.L().Warn("WebSocket升级失败", zap.Error(err)) return } client := NewClient(c.hub, conn, room, clientID) online := c.hub.Register(client) client.send <- OutgoingMessage{ Type: EventWelcome, Room: room, ClientID: clientID, Data: "connected", Online: online, Timestamp: time.Now(), } c.hub.Broadcast(room, presenceMessage(room, clientID, "joined", online)) go client.WritePump() client.ReadPump() } func randomClientID() string { value := make([]byte, 8) if _, err := rand.Read(value); err != nil { return "anonymous" } return hex.EncodeToString(value) }