Files
go-skeleton/modules/ws/controller.go
T

67 lines
1.6 KiB
Go

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)
}