| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- // Redis模块 - 负责Redis连接管理和消息存储
- package wsClient
- import (
- "context"
- "encoding/json"
- "log"
- "time"
- "github.com/redis/go-redis/v9"
- )
- // Redis客户端实例,全局变量
- var redisClient *redis.Client
- // Redis上下文
- var ctx = context.Background()
- // ChatMessage 表示存储在Redis中的聊天消息结构
- type ChatMessage struct {
- Content string `json:"content"` // 原始消息内容(JSON字符串)
- Timestamp time.Time `json:"timestamp"` // 存储时间戳
- RoomName string `json:"room_name"` // 房间名称
- }
- // InitRedis 初始化Redis连接
- func InitRedis(addr, password string, db int) error {
- redisClient = redis.NewClient(&redis.Options{
- Addr: addr, // Redis服务器地址 (例如: "localhost:6379")
- Password: password, // Redis密码 (如果没有密码则为空字符串)
- DB: db, // Redis数据库编号 (0-15)
- })
- // 测试Redis连接
- pong, err := redisClient.Ping(ctx).Result()
- if err != nil {
- log.Printf("Redis连接失败: %v", err)
- return err
- }
- log.Printf("Redis连接成功: %s", pong)
- return nil
- }
- // StoreRawMessage 将原始消息内容存储到Redis中
- // 使用房间名作为Redis列表的键,存储消息历史记录
- func StoreRawMessage(roomName string, rawMessage []byte) error {
- if redisClient == nil {
- log.Println("Redis客户端未初始化")
- return nil
- }
- // 创建消息对象,包含原始消息内容和时间戳
- chatMsg := ChatMessage{
- Content: string(rawMessage), // 直接存储原始JSON字符串
- Timestamp: time.Now(),
- RoomName: roomName,
- }
- // 将消息序列化为JSON
- msgBytes, err := json.Marshal(chatMsg)
- if err != nil {
- log.Printf("消息序列化失败: %v", err)
- return err
- }
- // 使用房间名作为Redis键,将消息添加到列表的右端
- // 键格式: "room_messages:{房间名}"
- key := "room_messages:" + roomName
- err = redisClient.RPush(ctx, key, msgBytes).Err()
- if err != nil {
- log.Printf("消息存储到Redis失败: %v", err)
- return err
- }
- // 设置过期时间(可选)- 7天后自动删除
- redisClient.Expire(ctx, key, 7*24*time.Hour)
- log.Printf("消息已存储到Redis - 房间: %s\n\n", roomName)
- return nil
- }
- // StoreMessage 将消息存储到Redis中(保留旧接口以兼容)
- // 使用房间名作为Redis列表的键,存储消息历史记录
- func StoreMessage(roomName, username, message string) error {
- if redisClient == nil {
- log.Println("Redis客户端未初始化")
- return nil
- }
- // 构建与新格式兼容的消息结构
- msgContent := map[string]interface{}{
- "name": username,
- "message": message,
- }
- msgBytes, _ := json.Marshal(msgContent)
-
- return StoreRawMessage(roomName, msgBytes)
- }
- // GetRoomMessages 获取房间的历史消息
- // 返回指定数量的最新消息
- func GetRoomMessages(roomName string, count int64) ([]ChatMessage, error) {
- if redisClient == nil {
- log.Println("Redis客户端未初始化")
- return nil, nil
- }
- key := "room_messages:" + roomName
-
- // 获取列表中的最新消息(从右端开始,即最新的消息)
- // -count 表示从列表末尾开始的count个元素
- result, err := redisClient.LRange(ctx, key, -count, -1).Result()
- if err != nil {
- log.Printf("从Redis获取消息失败: %v", err)
- return nil, err
- }
- var messages []ChatMessage
- for _, msgStr := range result {
- var msg ChatMessage
- if err := json.Unmarshal([]byte(msgStr), &msg); err != nil {
- log.Printf("消息反序列化失败: %v", err)
- continue
- }
- messages = append(messages, msg)
- }
- return messages, nil
- }
- // GetRoomMessageCount 获取房间的消息总数
- func GetRoomMessageCount(roomName string) (int64, error) {
- if redisClient == nil {
- return 0, nil
- }
- key := "room_messages:" + roomName
- return redisClient.LLen(ctx, key).Result()
- }
- // CloseRedis 关闭Redis连接
- func CloseRedis() error {
- if redisClient != nil {
- return redisClient.Close()
- }
- return nil
- }
|