init
This commit is contained in:
132
Backend/ws/hub.go
Normal file
132
Backend/ws/hub.go
Normal file
@@ -0,0 +1,132 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user