// Copyright © 2023 OpenIM open source community. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cache import ( "context" "time" "github.com/openimsdk/tools/errs" "github.com/redis/go-redis/v9" ) const ( userLoginIPPrefix = "CHAT:USER_LOGIN_IP:" // 缓存过期时间:7天(用户登录IP变化不频繁,可以设置较长的过期时间) userLoginIPExpire = 7 * 24 * time.Hour ) func getUserLoginIPKey(userID string) string { return userLoginIPPrefix + userID } type UserLoginIPInterface interface { // GetLatestLoginIP 获取用户最新登录IP(从缓存) // 返回值:(ip, found, error) // - ip: 缓存的IP值(如果found为false,则ip为空字符串) // - found: 是否在缓存中找到(true表示缓存命中,false表示缓存未命中) // - error: 错误信息 GetLatestLoginIP(ctx context.Context, userID string) (string, bool, error) // SetLatestLoginIP 设置用户最新登录IP到缓存 SetLatestLoginIP(ctx context.Context, userID, ip string) error // DeleteLatestLoginIP 删除用户最新登录IP缓存(用于保证缓存一致性) DeleteLatestLoginIP(ctx context.Context, userID string) error } type userLoginIPCacheRedis struct { rdb redis.UniversalClient } func NewUserLoginIPInterface(rdb redis.UniversalClient) UserLoginIPInterface { return &userLoginIPCacheRedis{rdb: rdb} } func (u *userLoginIPCacheRedis) GetLatestLoginIP(ctx context.Context, userID string) (string, bool, error) { key := getUserLoginIPKey(userID) ip, err := u.rdb.Get(ctx, key).Result() if err != nil { if err == redis.Nil { // 缓存不存在,返回 false 表示缓存未命中 return "", false, nil } return "", false, errs.Wrap(err) } // 缓存命中,返回 true return ip, true, nil } func (u *userLoginIPCacheRedis) SetLatestLoginIP(ctx context.Context, userID, ip string) error { key := getUserLoginIPKey(userID) err := u.rdb.Set(ctx, key, ip, userLoginIPExpire).Err() if err != nil { return errs.Wrap(err) } return nil } func (u *userLoginIPCacheRedis) DeleteLatestLoginIP(ctx context.Context, userID string) error { key := getUserLoginIPKey(userID) err := u.rdb.Del(ctx, key).Err() if err != nil { return errs.Wrap(err) } return nil }