67 lines
1.6 KiB
Go
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)
|
|
}
|