feat(ws): Task 1 - Hub 事件路由表机制

- Hub 新增 eventHandlers map + RegisterEvent / DispatchEvent 方法
- handler.go onMessage 优先查路由表,未命中走内置 fallback
- default 分支改为返回"未知事件"错误响应 + 警告日志

Made-with: Cursor
This commit is contained in:
bujinyuan
2026-03-03 10:43:01 +08:00
parent 6ab04fb902
commit c23b9087b8
2 changed files with 52 additions and 11 deletions

View File

@@ -7,23 +7,31 @@ import (
"go.uber.org/zap"
)
// EventHandler WS 事件处理函数签名
// 业务模块通过 Hub.RegisterEvent 注册处理器Hub 在消息分发时自动路由
type EventHandler func(client *Client, msg *Message)
// Hub 管理所有活跃的 WebSocket 客户端连接
// 提供按 userID 注册/注销/查找连接的能力,支持优雅关闭
// 同时维护事件路由表,将 WS 消息分发给对应的业务模块处理器
type Hub struct {
clients map[int64]*Client // userID -> Client 映射
register chan *Client // 注册通道
unregister chan *Client // 注销通道
mu sync.RWMutex // 保护 clients map 的读写锁
stopCh chan struct{} // 停止信号,用于优雅关闭 Run 循环
clients map[int64]*Client // userID -> Client 映射
register chan *Client // 注册通道
unregister chan *Client // 注销通道
mu sync.RWMutex // 保护 clients map 的读写锁
stopCh chan struct{} // 停止信号,用于优雅关闭 Run 循环
eventHandlers map[string]EventHandler // 事件路由表event -> handler
ehMu sync.RWMutex // 保护 eventHandlers 的读写锁
}
// NewHub 创建 Hub 实例
func NewHub() *Hub {
return &Hub{
clients: make(map[int64]*Client),
register: make(chan *Client, 256),
unregister: make(chan *Client, 256),
stopCh: make(chan struct{}),
clients: make(map[int64]*Client),
register: make(chan *Client, 256),
unregister: make(chan *Client, 256),
stopCh: make(chan struct{}),
eventHandlers: make(map[string]EventHandler),
}
}
@@ -143,3 +151,27 @@ func (h *Hub) IsOnline(userID int64) bool {
_, ok := h.clients[userID]
return ok
}
// RegisterEvent 注册事件处理器到路由表
// 业务模块在启动时调用,将 WS 事件映射到对应的处理函数
// 例如hub.RegisterEvent("im.message.send", handler.HandleSendMessage)
func (h *Hub) RegisterEvent(event string, handler EventHandler) {
h.ehMu.Lock()
defer h.ehMu.Unlock()
h.eventHandlers[event] = handler
logs.Info(nil, "ws.hub.RegisterEvent", "注册事件处理器",
zap.String("event", event))
}
// DispatchEvent 将消息分发到注册的事件处理器
// 返回 true 表示找到匹配的处理器并已执行false 表示无匹配需走 fallback 逻辑
func (h *Hub) DispatchEvent(client *Client, msg *Message) bool {
h.ehMu.RLock()
handler, ok := h.eventHandlers[msg.Event]
h.ehMu.RUnlock()
if !ok {
return false
}
handler(client, msg)
return true
}