diff --git a/service/imService.go b/service/imService.go index ec95b22..5f0e93e 100644 --- a/service/imService.go +++ b/service/imService.go @@ -15,11 +15,31 @@ func CreateGeneralMessageService(from_id, to_id, msg_type, group_id int, content var id uint switch msg_type { case proto.MSG_TYPE_SIMPLE: - //判断是否是好友 - friend := dao.FindFriend(from_id, to_id) - if len(friend) == 0 { - return errors.New("未添加好友"), 0 + //判断是否是好友,判断是否存在缓存,不存在则设置缓存,存在则判断是否是好友 + if worker.IsContainKey("user_"+strconv.Itoa(to_id)+"_friends") == false { + //设置好友缓存 + isSuccess := SetFriendCache(from_id) + //设置失败,直接查询数据库 + if !isSuccess { + friend := dao.FindFriend(from_id, to_id) + if len(friend) == 0 { + return errors.New("未添加好友"), 0 + } + } else { + //判断是否是好友-redis方式 + is_f := worker.IsContainSet("user_"+strconv.Itoa(to_id)+"_friends", strconv.Itoa(from_id)) + if !is_f { + return errors.New("未添加好友"), 0 + } + } + } else { + //判断是否是好友-redis方式 + is_f := worker.IsContainSet("user_"+strconv.Itoa(to_id)+"_friends", strconv.Itoa(from_id)) + if !is_f { + return errors.New("未添加好友"), 0 + } } + err, id = dao.CreateSimpleMessage(from_id, to_id, content) res := worker.GetRedis("user_" + strconv.Itoa(to_id) + "_status_v2") if res == "1" { @@ -30,11 +50,31 @@ func CreateGeneralMessageService(from_id, to_id, msg_type, group_id int, content if from_id == 0 || group_id == 0 || content == "" { return errors.New("参数错误"), 0 } - //判断该用户是否在群里 - groupUser := dao.FindGroupUser(from_id, group_id) - if len(groupUser) == 0 { - return errors.New("用户不在群里"), 0 + //判断是否在群里 + if worker.IsContainKey("group_"+strconv.Itoa(group_id)+"_users") == false { + //设置群缓存 + isSuccess := SetGroupCache(group_id) + //设置失败,直接查询数据库 + if !isSuccess { + groupUser := dao.FindGroupUser(from_id, group_id) + if len(groupUser) == 0 { + return errors.New("用户不在群里"), 0 + } + } else { + //判断该用户是否在群里-redis方式 + is_g := worker.IsContainSet("group_"+strconv.Itoa(group_id)+"_users", strconv.Itoa(from_id)) + if !is_g { + return errors.New("用户不在群里"), 0 + } + } + } else { + //判断该用户是否在群里-redis方式 + is_g := worker.IsContainSet("group_"+strconv.Itoa(group_id)+"_users", strconv.Itoa(from_id)) + if !is_g { + return errors.New("用户不在群里"), 0 + } } + err, id = dao.CreateGeneralMessage(from_id, to_id, msg_type, 0, group_id, content) //获取群里的用户 users := dao.FindGroupUsers(group_id) @@ -64,6 +104,7 @@ func CreateGeneralMessageService(from_id, to_id, msg_type, group_id int, content return errors.New("已有请求"), res[0].ID } err, id = dao.CreateGeneralMessage(from_id, to_id, msg_type, 0, group_id, content) + case proto.MSG_TYPE_GROUP_ADD: //加入群聊请求 //判断是否在群里 @@ -91,6 +132,13 @@ func CreateGeneralMessageService(from_id, to_id, msg_type, group_id int, content return errors.New("已在群里"), 0 } err, id = dao.JoinGroup(group_id, to_id) + if err == nil { + //设置群缓存,如果存在缓存则加入 + if worker.IsContainKey("group_"+strconv.Itoa(group_id)+"_users") == true { + //将用户加入群缓存 + worker.SetRedisSetAdd("group_"+strconv.Itoa(group_id)+"_users", strconv.Itoa(to_id)) + } + } default: // 未知消息类型 err = errors.New("unknown message type") @@ -130,7 +178,17 @@ func AddFriendService(id, from_user_id, to_user_id int) error { return errors.New("already a friend") } dao.UpdateMessageStatus(res[0].ID, 1) - return dao.AddFriend(from_user_id, to_user_id) + res2 := dao.AddFriend(from_user_id, to_user_id) + if res2 == nil { + //设置好友缓存 + if worker.IsContainKey("user_"+strconv.Itoa(from_user_id)+"_friends") == true { + worker.SetRedisSetAdd("user_"+strconv.Itoa(from_user_id)+"_friends", strconv.Itoa(to_user_id)) + } + if worker.IsContainKey("user_"+strconv.Itoa(to_user_id)+"_friends") == true { + worker.SetRedisSetAdd("user_"+strconv.Itoa(to_user_id)+"_friends", strconv.Itoa(from_user_id)) + } + } + return res2 } else if res[0].ToUserID == from_user_id && res[0].GroupID == to_user_id { //加入群聊 //查看是否已经加入 @@ -185,12 +243,20 @@ func GetFriendRequest(user_id int) []dao.FriendRequest { func DelFriendService(user_id, friend_id int) error { //删除好友 err := dao.DeleteFriend(user_id, friend_id) + //删除好友缓存 + if err == nil && worker.IsContainKey("user_"+strconv.Itoa(user_id)+"_friends") == true { + worker.SetRedisSetRemove("user_"+strconv.Itoa(user_id)+"_friends", strconv.Itoa(friend_id)) + } return err } func QuitGroupService(user_id, group_id int) error { //退出群聊 err := dao.QuitGroup(group_id, user_id) + //删除群缓存 + if err == nil && worker.IsContainKey("group_"+strconv.Itoa(group_id)+"_users") == true { + worker.SetRedisSetRemove("group_"+strconv.Itoa(group_id)+"_users", strconv.Itoa(user_id)) + } return err } func DelGroupService(user_id, group_id int) error { @@ -231,3 +297,27 @@ func GetGroupRequestUsers(user_id int) []dao.FriendRequest { users := dao.GetGroupRequestUsers(user_id) return users } + +// 设置用户朋友关系缓存 +func SetFriendCache(user_id int) bool { + //获取好友id + friends := dao.FindFriends(user_id) + var ids []string + for _, friend := range friends { + ids = append(ids, strconv.Itoa(friend.ID)) + } + res := worker.SetRedisSet("user_"+strconv.Itoa(user_id)+"_friends", ids, time.Hour*12) + return res +} + +// 设置用户群关系缓存 +func SetGroupCache(group_id int) bool { + //获取好友id + users := dao.FindGroupUsers(group_id) + var ids []string + for _, user := range users { + ids = append(ids, strconv.Itoa(user.UserID)) + } + res := worker.SetRedisSet("group_"+strconv.Itoa(group_id)+"_groups", ids, time.Hour*12) + return res +} diff --git a/worker/redis.go b/worker/redis.go index bc19b5f..5349147 100644 --- a/worker/redis.go +++ b/worker/redis.go @@ -255,3 +255,52 @@ func hGetRedis(key string, field string) string { } return val } + +// 设置set,有过期时间 +func SetRedisSet(key string, values []string, expire time.Duration) bool { + ctx := context.Background() + err := redisClient.SAdd(ctx, key, values).Err() + if err != nil { + fmt.Println("Error setting key: %v", err) + return false + } + err = redisClient.Expire(ctx, key, expire).Err() + if err != nil { + fmt.Println("Error setting key: %v", err) + return false + } + return true +} + +// 设置set,添加元素 +func SetRedisSetAdd(key string, value string) bool { + ctx := context.Background() + err := redisClient.SAdd(ctx, key, value).Err() + if err != nil { + fmt.Println("Error setting key: %v", err) + return false + } + return true +} + +// 设置set,删除元素 +func SetRedisSetRemove(key string, value string) bool { + ctx := context.Background() + err := redisClient.SRem(ctx, key, value).Err() + if err != nil { + fmt.Println("Error setting key: %v", err) + return false + } + return true +} + +// 查看set是否包含元素 +func IsContainSet(key string, value string) bool { + ctx := context.Background() + val, err := redisClient.SIsMember(ctx, key, value).Result() + if err != nil { + fmt.Println("Error getting key: %v", err) + return false + } + return val +}