mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-11-05 03:42:08 +08:00
online cache
This commit is contained in:
parent
45b07bc3cc
commit
32c5f65d2f
@ -17,13 +17,9 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/tools/system/program"
|
"github.com/openimsdk/tools/system/program"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if len(os.Args) == 1 {
|
|
||||||
os.Args = []string{os.Args[0], "-i", "0", "-c", "/Users/chao/Desktop/project/open-im-server/config"}
|
|
||||||
}
|
|
||||||
if err := cmd.NewConversationRpcCmd().Exec(); err != nil {
|
if err := cmd.NewConversationRpcCmd().Exec(); err != nil {
|
||||||
program.ExitWithError(err)
|
program.ExitWithError(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,13 +17,9 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/tools/system/program"
|
"github.com/openimsdk/tools/system/program"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if len(os.Args) == 1 {
|
|
||||||
os.Args = []string{os.Args[0], "-i", "0", "-c", "/Users/chao/Desktop/project/open-im-server/config"}
|
|
||||||
}
|
|
||||||
if err := cmd.NewGroupRpcCmd().Exec(); err != nil {
|
if err := cmd.NewGroupRpcCmd().Exec(); err != nil {
|
||||||
program.ExitWithError(err)
|
program.ExitWithError(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -140,7 +140,7 @@ func NewWsServer(msgGatewayConfig *Config, opts ...Option) *WsServer {
|
|||||||
unregisterChan: make(chan *Client, 1000),
|
unregisterChan: make(chan *Client, 1000),
|
||||||
kickHandlerChan: make(chan *kickHandler, 1000),
|
kickHandlerChan: make(chan *kickHandler, 1000),
|
||||||
validate: v,
|
validate: v,
|
||||||
clients: newUserMap(),
|
clients: newUserMap1(),
|
||||||
Compressor: NewGzipCompressor(),
|
Compressor: NewGzipCompressor(),
|
||||||
Encoder: NewGobEncoder(),
|
Encoder: NewGobEncoder(),
|
||||||
webhookClient: webhook.NewWebhookClient(msgGatewayConfig.WebhooksConfig.URL),
|
webhookClient: webhook.NewWebhookClient(msgGatewayConfig.WebhooksConfig.URL),
|
||||||
@ -345,7 +345,7 @@ func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Clien
|
|||||||
|
|
||||||
func (ws *WsServer) unregisterClient(client *Client) {
|
func (ws *WsServer) unregisterClient(client *Client) {
|
||||||
defer ws.clientPool.Put(client)
|
defer ws.clientPool.Put(client)
|
||||||
isDeleteUser := ws.clients.Delete(client.UserID, client.ctx.GetRemoteAddr())
|
isDeleteUser := ws.clients.DeleteClients(client.UserID, []*Client{client})
|
||||||
if isDeleteUser {
|
if isDeleteUser {
|
||||||
ws.onlineUserNum.Add(-1)
|
ws.onlineUserNum.Add(-1)
|
||||||
prommetrics.OnlineUserGauge.Dec()
|
prommetrics.OnlineUserGauge.Dec()
|
||||||
|
|||||||
@ -98,7 +98,7 @@ func (ws *WsServer) ChangeOnlineStatus(concurrent int) {
|
|||||||
case <-mergeTicker.C:
|
case <-mergeTicker.C:
|
||||||
pushAllUserState()
|
pushAllUserState()
|
||||||
case now := <-scanTicker.C:
|
case now := <-scanTicker.C:
|
||||||
pushUserState(ws.clients.GetAllUserStatus(now.Add(-cachekey.OnlineExpire/3), now)...)
|
pushUserState(ws.clients.GetAllUserStatus(now.Add(-cachekey.OnlineExpire / 3))...)
|
||||||
case state := <-ws.clients.UserState():
|
case state := <-ws.clients.UserState():
|
||||||
log.ZDebug(context.Background(), "user online change", "userID", state.UserID, "online", state.Online, "offline", state.Offline)
|
log.ZDebug(context.Background(), "user online change", "userID", state.UserID, "online", state.Online, "offline", state.Offline)
|
||||||
pushUserState(state)
|
pushUserState(state)
|
||||||
|
|||||||
@ -14,123 +14,153 @@
|
|||||||
|
|
||||||
package msggateway
|
package msggateway
|
||||||
|
|
||||||
//
|
import (
|
||||||
//import (
|
"context"
|
||||||
// "context"
|
"sync"
|
||||||
// "sync"
|
"time"
|
||||||
//
|
|
||||||
// "github.com/openimsdk/tools/log"
|
"github.com/openimsdk/tools/log"
|
||||||
// "github.com/openimsdk/tools/utils/datautil"
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
//)
|
)
|
||||||
//
|
|
||||||
//type UserMap struct {
|
func newUserMap1() UMap {
|
||||||
// m sync.Map
|
return &UserMap{
|
||||||
//}
|
ch: make(chan UserState, 1024),
|
||||||
//
|
}
|
||||||
//func newUserMap() UMap {
|
}
|
||||||
// return &UserMap{}
|
|
||||||
//}
|
type UserPlatform1 struct {
|
||||||
//
|
Time time.Time
|
||||||
//func (u *UserMap) GetAll(key string) ([]*Client, bool) {
|
Clients []*Client
|
||||||
// allClients, ok := u.m.Load(key)
|
}
|
||||||
// if ok {
|
|
||||||
// return allClients.([]*Client), ok
|
func (u *UserPlatform1) PlatformIDs() []int32 {
|
||||||
// }
|
if len(u.Clients) == 0 {
|
||||||
// return nil, ok
|
return nil
|
||||||
//}
|
}
|
||||||
//
|
platformIDs := make([]int32, 0, len(u.Clients))
|
||||||
//func (u *UserMap) Get(key string, platformID int) ([]*Client, bool, bool) {
|
for _, client := range u.Clients {
|
||||||
// allClients, userExisted := u.m.Load(key)
|
platformIDs = append(platformIDs, int32(client.PlatformID))
|
||||||
// if userExisted {
|
}
|
||||||
// var clients []*Client
|
return platformIDs
|
||||||
// for _, client := range allClients.([]*Client) {
|
}
|
||||||
// if client.PlatformID == platformID {
|
|
||||||
// clients = append(clients, client)
|
type UserMap struct {
|
||||||
// }
|
m sync.Map
|
||||||
// }
|
ch chan UserState
|
||||||
// if len(clients) > 0 {
|
}
|
||||||
// return clients, userExisted, true
|
|
||||||
// }
|
func (u *UserMap) UserState() <-chan UserState {
|
||||||
// return clients, userExisted, false
|
return u.ch
|
||||||
// }
|
}
|
||||||
// return nil, userExisted, false
|
|
||||||
//}
|
func (u *UserMap) GetAllUserStatus(deadline time.Time) []UserState {
|
||||||
//
|
var result []UserState
|
||||||
//// Set adds a client to the map.
|
u.m.Range(func(key, value any) bool {
|
||||||
//func (u *UserMap) Set(key string, v *Client) {
|
client := value.(*UserPlatform1)
|
||||||
// allClients, existed := u.m.Load(key)
|
if client.Time.Before(deadline) {
|
||||||
// if existed {
|
return true
|
||||||
// log.ZDebug(context.Background(), "Set existed", "user_id", key, "client_user_id", v.UserID)
|
}
|
||||||
// oldClients := allClients.([]*Client)
|
client.Time = time.Now()
|
||||||
// oldClients = append(oldClients, v)
|
us := UserState{
|
||||||
// u.m.Store(key, oldClients)
|
UserID: key.(string),
|
||||||
// } else {
|
Online: make([]int32, 0, len(client.Clients)),
|
||||||
// log.ZDebug(context.Background(), "Set not existed", "user_id", key, "client_user_id", v.UserID)
|
}
|
||||||
//
|
for _, c := range client.Clients {
|
||||||
// var clients []*Client
|
us.Online = append(us.Online, int32(c.PlatformID))
|
||||||
// clients = append(clients, v)
|
}
|
||||||
// u.m.Store(key, clients)
|
return true
|
||||||
// }
|
})
|
||||||
//}
|
return result
|
||||||
//
|
}
|
||||||
//func (u *UserMap) Delete(key string, connRemoteAddr string) (isDeleteUser bool) {
|
|
||||||
// // Attempt to load the clients associated with the key.
|
func (u *UserMap) push(userID string, userPlatform *UserPlatform1, offline []int32) bool {
|
||||||
// allClients, existed := u.m.Load(key)
|
select {
|
||||||
// if !existed {
|
case u.ch <- UserState{UserID: userID, Online: userPlatform.PlatformIDs(), Offline: offline}:
|
||||||
// // Return false immediately if the key does not exist.
|
userPlatform.Time = time.Now()
|
||||||
// return false
|
return true
|
||||||
// }
|
default:
|
||||||
//
|
return false
|
||||||
// // Convert allClients to a slice of *Client.
|
}
|
||||||
// oldClients := allClients.([]*Client)
|
}
|
||||||
// var remainingClients []*Client
|
|
||||||
// for _, client := range oldClients {
|
func (u *UserMap) GetAll(key string) ([]*Client, bool) {
|
||||||
// // Keep clients that do not match the connRemoteAddr.
|
allClients, ok := u.m.Load(key)
|
||||||
// if client.ctx.GetRemoteAddr() != connRemoteAddr {
|
if ok {
|
||||||
// remainingClients = append(remainingClients, client)
|
return allClients.(*UserPlatform1).Clients, ok
|
||||||
// }
|
}
|
||||||
// }
|
return nil, ok
|
||||||
//
|
}
|
||||||
// // If no clients remain after filtering, delete the key from the map.
|
|
||||||
// if len(remainingClients) == 0 {
|
func (u *UserMap) Get(key string, platformID int) ([]*Client, bool, bool) {
|
||||||
// u.m.Delete(key)
|
allClients, userExisted := u.m.Load(key)
|
||||||
// return true
|
if userExisted {
|
||||||
// }
|
var clients []*Client
|
||||||
//
|
for _, client := range allClients.(*UserPlatform1).Clients {
|
||||||
// // Otherwise, update the key with the remaining clients.
|
if client.PlatformID == platformID {
|
||||||
// u.m.Store(key, remainingClients)
|
clients = append(clients, client)
|
||||||
// return false
|
}
|
||||||
//}
|
}
|
||||||
//
|
if len(clients) > 0 {
|
||||||
//func (u *UserMap) DeleteClients(key string, clients []*Client) (isDeleteUser bool) {
|
return clients, true, true
|
||||||
// m := datautil.SliceToMapAny(clients, func(c *Client) (string, struct{}) {
|
}
|
||||||
// return c.ctx.GetRemoteAddr(), struct{}{}
|
return clients, true, false
|
||||||
// })
|
}
|
||||||
// allClients, existed := u.m.Load(key)
|
return nil, false, false
|
||||||
// if !existed {
|
}
|
||||||
// // If the key doesn't exist, return false.
|
|
||||||
// return false
|
// Set adds a client to the map.
|
||||||
// }
|
func (u *UserMap) Set(key string, v *Client) {
|
||||||
//
|
allClients, existed := u.m.Load(key)
|
||||||
// // Filter out clients that are in the deleteMap.
|
if existed {
|
||||||
// oldClients := allClients.([]*Client)
|
log.ZDebug(context.Background(), "Set existed", "user_id", key, "client_user_id", v.UserID)
|
||||||
// var remainingClients []*Client
|
oldClients := allClients.(*UserPlatform1)
|
||||||
// for _, client := range oldClients {
|
oldClients.Time = time.Now()
|
||||||
// if _, shouldBeDeleted := m[client.ctx.GetRemoteAddr()]; !shouldBeDeleted {
|
oldClients.Clients = append(oldClients.Clients, v)
|
||||||
// remainingClients = append(remainingClients, client)
|
u.push(key, oldClients, nil)
|
||||||
// }
|
} else {
|
||||||
// }
|
log.ZDebug(context.Background(), "Set not existed", "user_id", key, "client_user_id", v.UserID)
|
||||||
//
|
cli := &UserPlatform1{
|
||||||
// // Update or delete the key based on the remaining clients.
|
Time: time.Now(),
|
||||||
// if len(remainingClients) == 0 {
|
Clients: []*Client{v},
|
||||||
// u.m.Delete(key)
|
}
|
||||||
// return true
|
u.m.Store(key, cli)
|
||||||
// }
|
u.push(key, cli, nil)
|
||||||
//
|
}
|
||||||
// u.m.Store(key, remainingClients)
|
|
||||||
// return false
|
}
|
||||||
//}
|
|
||||||
//
|
func (u *UserMap) DeleteClients(key string, clients []*Client) (isDeleteUser bool) {
|
||||||
//func (u *UserMap) DeleteAll(key string) {
|
m := datautil.SliceToMapAny(clients, func(c *Client) (string, struct{}) {
|
||||||
// u.m.Delete(key)
|
return c.ctx.GetRemoteAddr(), struct{}{}
|
||||||
//}
|
})
|
||||||
|
allClients, existed := u.m.Load(key)
|
||||||
|
if !existed {
|
||||||
|
// If the key doesn't exist, return false.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter out clients that are in the deleteMap.
|
||||||
|
oldClients := allClients.(*UserPlatform1)
|
||||||
|
var (
|
||||||
|
remainingClients []*Client
|
||||||
|
offline []int32
|
||||||
|
)
|
||||||
|
for _, client := range oldClients.Clients {
|
||||||
|
if _, shouldBeDeleted := m[client.ctx.GetRemoteAddr()]; !shouldBeDeleted {
|
||||||
|
remainingClients = append(remainingClients, client)
|
||||||
|
} else {
|
||||||
|
offline = append(offline, int32(client.PlatformID))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oldClients.Clients = remainingClients
|
||||||
|
defer u.push(key, oldClients, offline)
|
||||||
|
// Update or delete the key based on the remaining clients.
|
||||||
|
if len(remainingClients) == 0 {
|
||||||
|
u.m.Delete(key)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
@ -9,10 +9,9 @@ type UMap interface {
|
|||||||
GetAll(userID string) ([]*Client, bool)
|
GetAll(userID string) ([]*Client, bool)
|
||||||
Get(userID string, platformID int) ([]*Client, bool, bool)
|
Get(userID string, platformID int) ([]*Client, bool, bool)
|
||||||
Set(userID string, v *Client)
|
Set(userID string, v *Client)
|
||||||
Delete(userID string, connRemoteAddr string) (isDeleteUser bool)
|
|
||||||
DeleteClients(userID string, clients []*Client) (isDeleteUser bool)
|
DeleteClients(userID string, clients []*Client) (isDeleteUser bool)
|
||||||
UserState() <-chan UserState
|
UserState() <-chan UserState
|
||||||
GetAllUserStatus(deadline, nowtime time.Time) []UserState
|
GetAllUserStatus(deadline time.Time) []UserState
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ UMap = (*UserMap2)(nil)
|
var _ UMap = (*UserMap2)(nil)
|
||||||
@ -102,26 +101,6 @@ func (u *UserMap2) Set(userID string, client *Client) {
|
|||||||
u.push(client.UserID, result, nil)
|
u.push(client.UserID, result, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserMap2) Delete(userID string, connRemoteAddr string) (isDeleteUser bool) {
|
|
||||||
u.lock.Lock()
|
|
||||||
defer u.lock.Unlock()
|
|
||||||
result, ok := u.data[userID]
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
client, ok := result.Clients[connRemoteAddr]
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
delete(result.Clients, connRemoteAddr)
|
|
||||||
defer u.push(userID, result, []int32{int32(client.PlatformID)})
|
|
||||||
if len(result.Clients) > 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
delete(u.data, userID)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *UserMap2) DeleteClients(userID string, clients []*Client) (isDeleteUser bool) {
|
func (u *UserMap2) DeleteClients(userID string, clients []*Client) (isDeleteUser bool) {
|
||||||
if len(clients) == 0 {
|
if len(clients) == 0 {
|
||||||
return false
|
return false
|
||||||
@ -145,7 +124,7 @@ func (u *UserMap2) DeleteClients(userID string, clients []*Client) (isDeleteUser
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserMap2) GetAllUserStatus(deadline, nowtime time.Time) []UserState {
|
func (u *UserMap2) GetAllUserStatus(deadline time.Time) []UserState {
|
||||||
u.lock.RLock()
|
u.lock.RLock()
|
||||||
defer u.lock.RUnlock()
|
defer u.lock.RUnlock()
|
||||||
if len(u.data) == 0 {
|
if len(u.data) == 0 {
|
||||||
@ -159,7 +138,7 @@ func (u *UserMap2) GetAllUserStatus(deadline, nowtime time.Time) []UserState {
|
|||||||
if p.Time.Before(deadline) {
|
if p.Time.Before(deadline) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
p.Time = nowtime
|
p.Time = time.Now()
|
||||||
online := make([]int32, 0, len(p.Clients))
|
online := make([]int32, 0, len(p.Clients))
|
||||||
for _, client := range p.Clients {
|
for _, client := range p.Clients {
|
||||||
online = append(online, int32(client.PlatformID))
|
online = append(online, int32(client.PlatformID))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user