feat(ws): 在线状态管理(Redis SET + TTL 心跳续期)

- app/ws/online_service.go: 上线/下线/心跳续期/批量查询在线状态
- 集成到 WebSocket handler: 连接时写入 Redis, 断线时清除
- client.go: 添加 DisconnectHandler 回调
- Redis 键: echo:user:online (SET) + echo:user:status:{uid} (TTL 60s)

Made-with: Cursor
This commit is contained in:
bujinyuan
2026-03-02 17:10:13 +08:00
parent 632e3b9a28
commit 1c87a466a1
6 changed files with 233 additions and 32 deletions

View File

@@ -17,13 +17,17 @@ const (
sendBufSize = 256 // 发送缓冲区大小
)
// DisconnectHandler 断线回调函数类型
type DisconnectHandler func(userID int64)
// Client 封装单个 WebSocket 客户端连接
// 每个连接持有两个 goroutinereadPump读取客户端消息和 writePump写入消息到客户端
type Client struct {
hub *Hub
conn *websocket.Conn
send chan []byte // 待发送消息缓冲队列
UserID int64 // 关联的用户 ID
hub *Hub
conn *websocket.Conn
send chan []byte // 待发送消息缓冲队列
UserID int64 // 关联的用户 ID
onDisconnect DisconnectHandler // 断线回调(清理在线状态等)
}
// NewClient 创建客户端实例
@@ -36,6 +40,11 @@ func NewClient(hub *Hub, conn *websocket.Conn, userID int64) *Client {
}
}
// SetOnDisconnect 设置断线回调
func (c *Client) SetOnDisconnect(handler DisconnectHandler) {
c.onDisconnect = handler
}
// MessageHandler 消息处理回调函数类型
type MessageHandler func(client *Client, msg *Message)
@@ -45,6 +54,9 @@ func (c *Client) ReadPump(onMessage MessageHandler) {
defer func() {
c.hub.Unregister(c)
c.conn.Close()
if c.onDisconnect != nil {
c.onDisconnect(c.UserID)
}
}()
c.conn.SetReadLimit(maxMessageSize)