// Package websocket 实现WebSocket连接管理和消息广播 // 为在线协作功能预留,支持多客户端实时通信 package websocket import ( "log" "sync" "github.com/gorilla/websocket" ) // Hub WebSocket连接管理中心 // 负责维护所有活跃的WebSocket连接,处理消息广播 type Hub struct { clients map[*Client]bool // 所有已连接的客户端 broadcast chan []byte // 待广播的消息通道 register chan *Client // 客户端注册通道 unregister chan *Client // 客户端注销通道 mu sync.RWMutex // 读写锁,保护 clients map } // Client 单个WebSocket客户端连接 type Client struct { hub *Hub // 所属的Hub conn *websocket.Conn // WebSocket连接实例 send chan []byte // 待发送的消息队列 } // NewHub 创建并返回一个新的Hub实例 func NewHub() *Hub { return &Hub{ clients: make(map[*Client]bool), broadcast: make(chan []byte, 256), register: make(chan *Client), unregister: make(chan *Client), } } // Run 启动Hub的主循环 // 在独立的goroutine中运行,处理客户端注册、注销和消息广播 func (h *Hub) Run() { for { select { case client := <-h.register: // 新客户端连接注册 h.mu.Lock() h.clients[client] = true h.mu.Unlock() log.Printf("WebSocket客户端已连接,当前在线: %d", len(h.clients)) case client := <-h.unregister: // 客户端断开连接注销 h.mu.Lock() if _, ok := h.clients[client]; ok { delete(h.clients, client) close(client.send) } h.mu.Unlock() log.Printf("WebSocket客户端已断开,当前在线: %d", len(h.clients)) case message := <-h.broadcast: // 向所有客户端广播消息 h.mu.RLock() for client := range h.clients { select { case client.send <- message: default: // 发送缓冲区已满,断开该客户端 close(client.send) delete(h.clients, client) } } h.mu.RUnlock() } } } // BroadcastMessage 向所有连接的客户端广播消息 // message: 要广播的字节数据 func (h *Hub) BroadcastMessage(message []byte) { h.broadcast <- message } // ClientCount 返回当前在线客户端数量 func (h *Hub) ClientCount() int { h.mu.RLock() defer h.mu.RUnlock() return len(h.clients) }