mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-05-21 12:19:18 +08:00
Get user online status (#693)
* Resolving code conflicts after project directory changes and Add subscribe and unsubscribe mongodb operations * Organize and update module dependencies * Get user online status * Get user online status * Get user online status
This commit is contained in:
parent
8979b9dce1
commit
e24b0e2114
@ -81,6 +81,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
|||||||
userRouterGroup.POST("/get_users_online_token_detail", ParseToken, u.GetUsersOnlineTokenDetail)
|
userRouterGroup.POST("/get_users_online_token_detail", ParseToken, u.GetUsersOnlineTokenDetail)
|
||||||
userRouterGroup.POST("/subscribe_users_status", ParseToken, u.UnSubscriberStatus)
|
userRouterGroup.POST("/subscribe_users_status", ParseToken, u.UnSubscriberStatus)
|
||||||
userRouterGroup.POST("/unsubscribe_users_status", ParseToken, u.UnSubscriberStatus)
|
userRouterGroup.POST("/unsubscribe_users_status", ParseToken, u.UnSubscriberStatus)
|
||||||
|
userRouterGroup.POST("/get_users_status", ParseToken, u.GetUserStatus)
|
||||||
|
|
||||||
}
|
}
|
||||||
// friend routing group
|
// friend routing group
|
||||||
|
@ -194,3 +194,7 @@ func (u *UserApi) SubscriberStatus(c *gin.Context) {
|
|||||||
func (u *UserApi) UnSubscriberStatus(c *gin.Context) {
|
func (u *UserApi) UnSubscriberStatus(c *gin.Context) {
|
||||||
a2r.Call(user.UserClient.SubscribeOrCancelUsersStatus, u.Client, c)
|
a2r.Call(user.UserClient.SubscribeOrCancelUsersStatus, u.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *UserApi) GetUserStatus(c *gin.Context) {
|
||||||
|
a2r.Call(user.UserClient.GetUserStatus, u.Client, c)
|
||||||
|
}
|
||||||
|
@ -261,11 +261,18 @@ func (s *userServer) SubscribeOrCancelUsersStatus(ctx context.Context, req *pbus
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) GetUserStatus(ctx context.Context, req *pbuser.GetUserStatusReq) (resp *pbuser.GetUserStatusResp, err error) {
|
func (s *userServer) GetUserStatus(ctx context.Context, req *pbuser.GetUserStatusReq) (resp *pbuser.GetUserStatusResp, err error) {
|
||||||
//TODO implement me
|
//TODO 是否加一个参数校验-判断req.userID的数量,每一个获取加一个限制,一次请求限制500?
|
||||||
panic("implement me")
|
onlineStatusList, err := s.UserDatabase.GetUserStatus(ctx, req.UserIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &pbuser.GetUserStatusResp{StatusList: onlineStatusList}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) SetUserStatus(ctx context.Context, req *pbuser.SetUserStatusReq) (resp *pbuser.SetUserStatusResp, err error) {
|
func (s *userServer) SetUserStatus(ctx context.Context, req *pbuser.SetUserStatusReq) (resp *pbuser.SetUserStatusResp, err error) {
|
||||||
//TODO implement me
|
err = s.UserDatabase.SetUserStatus(ctx, req.StatusList)
|
||||||
panic("implement me")
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &pbuser.SetUserStatusResp{}, nil
|
||||||
}
|
}
|
||||||
|
79
pkg/common/db/cache/user.go
vendored
79
pkg/common/db/cache/user.go
vendored
@ -16,6 +16,9 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/OpenIMSDK/protocol/user"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dtm-labs/rockscache"
|
"github.com/dtm-labs/rockscache"
|
||||||
@ -28,6 +31,9 @@ const (
|
|||||||
userExpireTime = time.Second * 60 * 60 * 12
|
userExpireTime = time.Second * 60 * 60 * 12
|
||||||
userInfoKey = "USER_INFO:"
|
userInfoKey = "USER_INFO:"
|
||||||
userGlobalRecvMsgOptKey = "USER_GLOBAL_RECV_MSG_OPT_KEY:"
|
userGlobalRecvMsgOptKey = "USER_GLOBAL_RECV_MSG_OPT_KEY:"
|
||||||
|
olineStatusKey = "ONLINE_STATUS:"
|
||||||
|
userOlineStatusExpireTime = time.Second * 60 * 60 * 24
|
||||||
|
statusMod = 500
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserCache interface {
|
type UserCache interface {
|
||||||
@ -38,10 +44,13 @@ type UserCache interface {
|
|||||||
DelUsersInfo(userIDs ...string) UserCache
|
DelUsersInfo(userIDs ...string) UserCache
|
||||||
GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error)
|
GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error)
|
||||||
DelUsersGlobalRecvMsgOpt(userIDs ...string) UserCache
|
DelUsersGlobalRecvMsgOpt(userIDs ...string) UserCache
|
||||||
|
GetUserStatus(ctx context.Context, userIDs []string) ([]*user.OnlineStatus, error)
|
||||||
|
SetUserStatus(ctx context.Context, list []*user.OnlineStatus) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserCacheRedis struct {
|
type UserCacheRedis struct {
|
||||||
metaCache
|
metaCache
|
||||||
|
rdb redis.UniversalClient
|
||||||
userDB relationTb.UserModelInterface
|
userDB relationTb.UserModelInterface
|
||||||
expireTime time.Duration
|
expireTime time.Duration
|
||||||
rcClient *rockscache.Client
|
rcClient *rockscache.Client
|
||||||
@ -54,6 +63,7 @@ func NewUserCacheRedis(
|
|||||||
) UserCache {
|
) UserCache {
|
||||||
rcClient := rockscache.NewClient(rdb, options)
|
rcClient := rockscache.NewClient(rdb, options)
|
||||||
return &UserCacheRedis{
|
return &UserCacheRedis{
|
||||||
|
rdb: rdb,
|
||||||
metaCache: NewMetaCacheRedis(rcClient),
|
metaCache: NewMetaCacheRedis(rcClient),
|
||||||
userDB: userDB,
|
userDB: userDB,
|
||||||
expireTime: userExpireTime,
|
expireTime: userExpireTime,
|
||||||
@ -63,6 +73,7 @@ func NewUserCacheRedis(
|
|||||||
|
|
||||||
func (u *UserCacheRedis) NewCache() UserCache {
|
func (u *UserCacheRedis) NewCache() UserCache {
|
||||||
return &UserCacheRedis{
|
return &UserCacheRedis{
|
||||||
|
rdb: u.rdb,
|
||||||
metaCache: NewMetaCacheRedis(u.rcClient, u.metaCache.GetPreDelKeys()...),
|
metaCache: NewMetaCacheRedis(u.rcClient, u.metaCache.GetPreDelKeys()...),
|
||||||
userDB: u.userDB,
|
userDB: u.userDB,
|
||||||
expireTime: u.expireTime,
|
expireTime: u.expireTime,
|
||||||
@ -145,3 +156,71 @@ func (u *UserCacheRedis) DelUsersGlobalRecvMsgOpt(userIDs ...string) UserCache {
|
|||||||
cache.AddKeys(keys...)
|
cache.AddKeys(keys...)
|
||||||
return cache
|
return cache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *UserCacheRedis) getOnlineStatusKey(userID string) string {
|
||||||
|
return olineStatusKey + userID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserStatus get user status
|
||||||
|
func (u *UserCacheRedis) GetUserStatus(ctx context.Context, userIDs []string) ([]*user.OnlineStatus, error) {
|
||||||
|
var res []*user.OnlineStatus
|
||||||
|
for _, userID := range userIDs {
|
||||||
|
UserIDNum, err := strconv.Atoi(userID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var modKey = strconv.Itoa(UserIDNum % statusMod)
|
||||||
|
var onlineStatus user.OnlineStatus
|
||||||
|
key := olineStatusKey + modKey
|
||||||
|
result, err := u.rdb.HGet(ctx, key, userID).Result()
|
||||||
|
if err != nil {
|
||||||
|
if err == redis.Nil {
|
||||||
|
// key or field does not exist
|
||||||
|
res = append(res, &user.OnlineStatus{
|
||||||
|
UserID: userID,
|
||||||
|
Status: 0,
|
||||||
|
PlatformID: -1,
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = json.Unmarshal([]byte(result), &onlineStatus)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
onlineStatus.UserID = userID
|
||||||
|
res = append(res, &onlineStatus)
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUserStatus Set the user status and save it in redis
|
||||||
|
func (u *UserCacheRedis) SetUserStatus(ctx context.Context, list []*user.OnlineStatus) error {
|
||||||
|
for _, status := range list {
|
||||||
|
var isNewKey int64
|
||||||
|
UserIDNum, err := strconv.Atoi(status.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var modKey = strconv.Itoa(UserIDNum % statusMod)
|
||||||
|
key := olineStatusKey + modKey
|
||||||
|
jsonData, err := json.Marshal(status)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
isNewKey, err = u.rdb.Exists(ctx, key).Result()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = u.rdb.HSet(ctx, key, status.UserID, string(jsonData)).Result()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if isNewKey > 0 {
|
||||||
|
u.rdb.Expire(ctx, key, userOlineStatusExpireTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
unRelationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
unRelationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
|
"github.com/OpenIMSDK/protocol/user"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
|
||||||
@ -56,6 +57,10 @@ type UserDatabase interface {
|
|||||||
GetAllSubscribeList(ctx context.Context, userID string) ([]string, error)
|
GetAllSubscribeList(ctx context.Context, userID string) ([]string, error)
|
||||||
// GetSubscribedList Get all subscribed lists
|
// GetSubscribedList Get all subscribed lists
|
||||||
GetSubscribedList(ctx context.Context, userID string) ([]string, error)
|
GetSubscribedList(ctx context.Context, userID string) ([]string, error)
|
||||||
|
// GetUserStatus Get the online status of the user
|
||||||
|
GetUserStatus(ctx context.Context, userIDs []string) ([]*user.OnlineStatus, error)
|
||||||
|
// SetUserStatus Set the user status and store the user status in redis
|
||||||
|
SetUserStatus(ctx context.Context, list []*user.OnlineStatus) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type userDatabase struct {
|
type userDatabase struct {
|
||||||
@ -195,3 +200,14 @@ func (u *userDatabase) GetSubscribedList(ctx context.Context, userID string) ([]
|
|||||||
//TODO 获取所有被订阅
|
//TODO 获取所有被订阅
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetUserStatus get user status
|
||||||
|
func (u *userDatabase) GetUserStatus(ctx context.Context, userIDs []string) ([]*user.OnlineStatus, error) {
|
||||||
|
onlineStatusList, err := u.cache.GetUserStatus(ctx, userIDs)
|
||||||
|
return onlineStatusList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUserStatus Set the user status and save it in redis
|
||||||
|
func (u *userDatabase) SetUserStatus(ctx context.Context, list []*user.OnlineStatus) error {
|
||||||
|
return u.cache.SetUserStatus(ctx, list)
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user