Files
TrangleAgent/Backend/ws/hub.go
2026-01-18 18:20:40 +08:00

133 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package ws
import (
"sync"
chatmodel "leke/ws/model" // 按实际路径修改
)
// Hub 聊天中枢:管理所有连接和房间
type Hub struct {
mu sync.RWMutex
// 所有在线用户userId -> Client
clients map[uint64]*Client
// 房间成员roomId -> (userId -> Client)
rooms map[string]map[uint64]*Client
}
// 全局唯一 Hub简单起见用一个全局变量
var ChatHub = NewHub()
// NewHub 创建一个新的 Hub 实例
func NewHub() *Hub {
return &Hub{
clients: make(map[uint64]*Client),
rooms: make(map[string]map[uint64]*Client),
}
}
// Register 注册新连接
func (h *Hub) Register(c *Client) {
h.mu.Lock()
defer h.mu.Unlock()
h.clients[c.UserId] = c
// 默认认为所有在线用户都在世界频道,这里你可以根据需要扩展
}
// Unregister 移除连接(断线/退出)
func (h *Hub) Unregister(c *Client) {
h.mu.Lock()
defer h.mu.Unlock()
delete(h.clients, c.UserId)
// 同时把他从所有房间移除
for roomId, members := range h.rooms {
if _, ok := members[c.UserId]; ok {
delete(members, c.UserId)
if len(members) == 0 {
delete(h.rooms, roomId)
}
}
}
}
// JoinRoom 加入房间
func (h *Hub) JoinRoom(userId uint64, roomId string) {
h.mu.Lock()
defer h.mu.Unlock()
client, ok := h.clients[userId]
if !ok {
return
}
members, ok := h.rooms[roomId]
if !ok {
members = make(map[uint64]*Client)
h.rooms[roomId] = members
}
members[userId] = client
client.Rooms[roomId] = true
}
// LeaveRoom 离开房间
func (h *Hub) LeaveRoom(userId uint64, roomId string) {
h.mu.Lock()
defer h.mu.Unlock()
client, ok := h.clients[userId]
if !ok {
return
}
if members, ok := h.rooms[roomId]; ok {
delete(members, userId)
if len(members) == 0 {
delete(h.rooms, roomId)
}
}
delete(client.Rooms, roomId)
}
// BroadcastWorld 向所有在线用户发送世界频道消息
func (h *Hub) BroadcastWorld(msg *chatmodel.ChatMessage) {
h.mu.RLock()
defer h.mu.RUnlock()
for _, client := range h.clients {
_ = client.EnqueueMessage(msg)
}
}
// BroadcastRoom 向房间内所有用户发送消息
func (h *Hub) BroadcastRoom(roomId string, msg *chatmodel.ChatMessage) {
h.mu.RLock()
defer h.mu.RUnlock()
members, ok := h.rooms[roomId]
if !ok {
return
}
for _, client := range members {
_ = client.EnqueueMessage(msg)
}
}
// SendPrivate 发送私聊消息
func (h *Hub) SendPrivate(fromUserId, toUserId uint64, msg *chatmodel.ChatMessage) {
h.mu.RLock()
defer h.mu.RUnlock()
toClient, ok := h.clients[toUserId]
if !ok {
return // 对方不在线可以后面扩展离线消息存DB
}
msg.FromUserId = fromUserId
_ = toClient.EnqueueMessage(msg)
}