mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-11-05 03:42:08 +08:00
sub
This commit is contained in:
parent
67d17c82d5
commit
9a4f5f78cb
2
go.mod
2
go.mod
@ -175,3 +175,5 @@ require (
|
|||||||
golang.org/x/crypto v0.21.0 // indirect
|
golang.org/x/crypto v0.21.0 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
replace github.com/openimsdk/protocol => /Users/chao/Desktop/project/protocol
|
||||||
|
|||||||
2
go.sum
2
go.sum
@ -262,8 +262,6 @@ github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y=
|
|||||||
github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
|
github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
|
||||||
github.com/openimsdk/gomake v0.0.14-alpha.5 h1:VY9c5x515lTfmdhhPjMvR3BBRrRquAUCFsz7t7vbv7Y=
|
github.com/openimsdk/gomake v0.0.14-alpha.5 h1:VY9c5x515lTfmdhhPjMvR3BBRrRquAUCFsz7t7vbv7Y=
|
||||||
github.com/openimsdk/gomake v0.0.14-alpha.5/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI=
|
github.com/openimsdk/gomake v0.0.14-alpha.5/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI=
|
||||||
github.com/openimsdk/protocol v0.0.69-alpha.24 h1:TYcNJeWOTuE40UQ54eNPdDdy0KTOh9rAOgax8lCyhDc=
|
|
||||||
github.com/openimsdk/protocol v0.0.69-alpha.24/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8=
|
|
||||||
github.com/openimsdk/tools v0.0.49-alpha.45 h1:XIzCoef4myybOiIlGuRY9FTtGBisZFC4Uy4PhG0ZWQ0=
|
github.com/openimsdk/tools v0.0.49-alpha.45 h1:XIzCoef4myybOiIlGuRY9FTtGBisZFC4Uy4PhG0ZWQ0=
|
||||||
github.com/openimsdk/tools v0.0.49-alpha.45/go.mod h1:HtSRjPTL8PsuZ+PhR5noqzrYBF0sdwW3/O/sWVucWg8=
|
github.com/openimsdk/tools v0.0.49-alpha.45/go.mod h1:HtSRjPTL8PsuZ+PhR5noqzrYBF0sdwW3/O/sWVucWg8=
|
||||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||||
|
|||||||
@ -72,8 +72,8 @@ type Client struct {
|
|||||||
closed atomic.Bool
|
closed atomic.Bool
|
||||||
closedErr error
|
closedErr error
|
||||||
token string
|
token string
|
||||||
//subLock sync.Mutex
|
subLock sync.Mutex
|
||||||
//subUserIDs map[string]struct{}
|
subUserIDs map[string]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetClient updates the client's state with new connection and context information.
|
// ResetClient updates the client's state with new connection and context information.
|
||||||
@ -204,6 +204,8 @@ func (c *Client) handleMessage(message []byte) error {
|
|||||||
resp, messageErr = c.longConnServer.UserLogout(ctx, binaryReq)
|
resp, messageErr = c.longConnServer.UserLogout(ctx, binaryReq)
|
||||||
case WsSetBackgroundStatus:
|
case WsSetBackgroundStatus:
|
||||||
resp, messageErr = c.setAppBackgroundStatus(ctx, binaryReq)
|
resp, messageErr = c.setAppBackgroundStatus(ctx, binaryReq)
|
||||||
|
case WsSubUserOnlineStatus:
|
||||||
|
resp, messageErr = c.longConnServer.SubUserOnlineStatus(ctx, c, binaryReq)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"ReqIdentifier failed,sendID:%s,msgIncr:%s,reqIdentifier:%d",
|
"ReqIdentifier failed,sendID:%s,msgIncr:%s,reqIdentifier:%d",
|
||||||
|
|||||||
@ -16,10 +16,10 @@ package msggateway
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
"unsafe"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func mockRandom() []byte {
|
func mockRandom() []byte {
|
||||||
@ -132,3 +132,8 @@ func BenchmarkDecompressWithSyncPool(b *testing.B) {
|
|||||||
assert.Equal(b, nil, err)
|
assert.Equal(b, nil, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestName(t *testing.T) {
|
||||||
|
t.Log(unsafe.Sizeof(Client{}))
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -43,6 +43,7 @@ const (
|
|||||||
WSKickOnlineMsg = 2002
|
WSKickOnlineMsg = 2002
|
||||||
WsLogoutMsg = 2003
|
WsLogoutMsg = 2003
|
||||||
WsSetBackgroundStatus = 2004
|
WsSetBackgroundStatus = 2004
|
||||||
|
WsSubUserOnlineStatus = 2005
|
||||||
WSDataError = 3001
|
WSDataError = 3001
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
"github.com/openimsdk/protocol/constant"
|
"github.com/openimsdk/protocol/constant"
|
||||||
"github.com/openimsdk/protocol/msggateway"
|
"github.com/openimsdk/protocol/msggateway"
|
||||||
"github.com/openimsdk/tools/discovery"
|
"github.com/openimsdk/tools/discovery"
|
||||||
@ -31,6 +32,10 @@ import (
|
|||||||
func (s *Server) InitServer(ctx context.Context, config *Config, disCov discovery.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func (s *Server) InitServer(ctx context.Context, config *Config, disCov discovery.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
s.LongConnServer.SetDiscoveryRegistry(disCov, config)
|
s.LongConnServer.SetDiscoveryRegistry(disCov, config)
|
||||||
msggateway.RegisterMsgGatewayServer(server, s)
|
msggateway.RegisterMsgGatewayServer(server, s)
|
||||||
|
s.userRcp = rpcclient.NewUserRpcClient(disCov, config.Share.RpcRegisterName.User, config.Share.IMAdminUserID)
|
||||||
|
if s.ready != nil {
|
||||||
|
return s.ready(s)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,18 +55,21 @@ type Server struct {
|
|||||||
LongConnServer LongConnServer
|
LongConnServer LongConnServer
|
||||||
config *Config
|
config *Config
|
||||||
pushTerminal map[int]struct{}
|
pushTerminal map[int]struct{}
|
||||||
|
ready func(srv *Server) error
|
||||||
|
userRcp rpcclient.UserRpcClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) SetLongConnServer(LongConnServer LongConnServer) {
|
func (s *Server) SetLongConnServer(LongConnServer LongConnServer) {
|
||||||
s.LongConnServer = LongConnServer
|
s.LongConnServer = LongConnServer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(rpcPort int, longConnServer LongConnServer, conf *Config) *Server {
|
func NewServer(rpcPort int, longConnServer LongConnServer, conf *Config, ready func(srv *Server) error) *Server {
|
||||||
s := &Server{
|
s := &Server{
|
||||||
rpcPort: rpcPort,
|
rpcPort: rpcPort,
|
||||||
LongConnServer: longConnServer,
|
LongConnServer: longConnServer,
|
||||||
pushTerminal: make(map[int]struct{}),
|
pushTerminal: make(map[int]struct{}),
|
||||||
config: conf,
|
config: conf,
|
||||||
|
ready: ready,
|
||||||
}
|
}
|
||||||
s.pushTerminal[constant.IOSPlatformID] = struct{}{}
|
s.pushTerminal[constant.IOSPlatformID] = struct{}{}
|
||||||
s.pushTerminal[constant.AndroidPlatformID] = struct{}{}
|
s.pushTerminal[constant.AndroidPlatformID] = struct{}{}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ package msggateway
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpccache"
|
||||||
"github.com/openimsdk/tools/db/redisutil"
|
"github.com/openimsdk/tools/db/redisutil"
|
||||||
"github.com/openimsdk/tools/utils/datautil"
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
"time"
|
"time"
|
||||||
@ -56,11 +57,13 @@ func Start(ctx context.Context, index int, conf *Config) error {
|
|||||||
WithMessageMaxMsgLength(conf.MsgGateway.LongConnSvr.WebsocketMaxMsgLen),
|
WithMessageMaxMsgLength(conf.MsgGateway.LongConnSvr.WebsocketMaxMsgLen),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
hubServer := NewServer(rpcPort, longServer, conf, func(srv *Server) error {
|
||||||
|
longServer.online = rpccache.NewOnlineCache(srv.userRcp, nil, rdb, longServer.subscriberUserOnlineStatusChanges)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
go longServer.ChangeOnlineStatus(4)
|
go longServer.ChangeOnlineStatus(4)
|
||||||
|
|
||||||
go longServer.SubscriberUserOnlineStatusChanges(rdb)
|
|
||||||
|
|
||||||
hubServer := NewServer(rpcPort, longServer, conf)
|
|
||||||
netDone := make(chan error)
|
netDone := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
err = hubServer.Start(ctx, index, conf)
|
err = hubServer.Start(ctx, index, conf)
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/webhook"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/webhook"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpccache"
|
||||||
pbAuth "github.com/openimsdk/protocol/auth"
|
pbAuth "github.com/openimsdk/protocol/auth"
|
||||||
"github.com/openimsdk/tools/mcontext"
|
"github.com/openimsdk/tools/mcontext"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -48,6 +49,7 @@ type LongConnServer interface {
|
|||||||
KickUserConn(client *Client) error
|
KickUserConn(client *Client) error
|
||||||
UnRegister(c *Client)
|
UnRegister(c *Client)
|
||||||
SetKickHandlerInfo(i *kickHandler)
|
SetKickHandlerInfo(i *kickHandler)
|
||||||
|
SubUserOnlineStatus(ctx context.Context, client *Client, data *Req) ([]byte, error)
|
||||||
Compressor
|
Compressor
|
||||||
Encoder
|
Encoder
|
||||||
MessageHandler
|
MessageHandler
|
||||||
@ -61,7 +63,8 @@ type WsServer struct {
|
|||||||
unregisterChan chan *Client
|
unregisterChan chan *Client
|
||||||
kickHandlerChan chan *kickHandler
|
kickHandlerChan chan *kickHandler
|
||||||
clients UserMap
|
clients UserMap
|
||||||
//subscription *Subscription
|
online *rpccache.OnlineCache
|
||||||
|
subscription *Subscription
|
||||||
clientPool sync.Pool
|
clientPool sync.Pool
|
||||||
onlineUserNum atomic.Int64
|
onlineUserNum atomic.Int64
|
||||||
onlineUserConnNum atomic.Int64
|
onlineUserConnNum atomic.Int64
|
||||||
@ -125,6 +128,8 @@ func NewWsServer(msgGatewayConfig *Config, opts ...Option) *WsServer {
|
|||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&config)
|
o(&config)
|
||||||
}
|
}
|
||||||
|
//userRpcClient := rpcclient.NewUserRpcClient(client, config.Share.RpcRegisterName.User, config.Share.IMAdminUserID)
|
||||||
|
|
||||||
v := validator.New()
|
v := validator.New()
|
||||||
return &WsServer{
|
return &WsServer{
|
||||||
msgGatewayConfig: msgGatewayConfig,
|
msgGatewayConfig: msgGatewayConfig,
|
||||||
@ -142,7 +147,7 @@ func NewWsServer(msgGatewayConfig *Config, opts ...Option) *WsServer {
|
|||||||
kickHandlerChan: make(chan *kickHandler, 1000),
|
kickHandlerChan: make(chan *kickHandler, 1000),
|
||||||
validate: v,
|
validate: v,
|
||||||
clients: newUserMap(),
|
clients: newUserMap(),
|
||||||
//subscription: newSubscription(),
|
subscription: newSubscription(),
|
||||||
Compressor: NewGzipCompressor(),
|
Compressor: NewGzipCompressor(),
|
||||||
Encoder: NewGobEncoder(),
|
Encoder: NewGobEncoder(),
|
||||||
webhookClient: webhook.NewWebhookClient(msgGatewayConfig.WebhooksConfig.URL),
|
webhookClient: webhook.NewWebhookClient(msgGatewayConfig.WebhooksConfig.URL),
|
||||||
@ -353,6 +358,9 @@ func (ws *WsServer) unregisterClient(client *Client) {
|
|||||||
prommetrics.OnlineUserGauge.Dec()
|
prommetrics.OnlineUserGauge.Dec()
|
||||||
}
|
}
|
||||||
ws.onlineUserConnNum.Add(-1)
|
ws.onlineUserConnNum.Add(-1)
|
||||||
|
client.subLock.Lock()
|
||||||
|
clear(client.subUserIDs)
|
||||||
|
client.subLock.Unlock()
|
||||||
//ws.SetUserOnlineStatus(client.ctx, client, constant.Offline)
|
//ws.SetUserOnlineStatus(client.ctx, client, constant.Offline)
|
||||||
log.ZInfo(client.ctx, "user offline", "close reason", client.closedErr, "online user Num",
|
log.ZInfo(client.ctx, "user offline", "close reason", client.closedErr, "online user Num",
|
||||||
ws.onlineUserNum.Load(), "online user conn Num",
|
ws.onlineUserNum.Load(), "online user conn Num",
|
||||||
|
|||||||
@ -2,174 +2,180 @@ package msggateway
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
|
"encoding/json"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/util/useronline"
|
"github.com/openimsdk/protocol/constant"
|
||||||
|
"github.com/openimsdk/protocol/sdkws"
|
||||||
"github.com/openimsdk/tools/log"
|
"github.com/openimsdk/tools/log"
|
||||||
"github.com/openimsdk/tools/mcontext"
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/openimsdk/tools/utils/idutil"
|
||||||
"math/rand"
|
"google.golang.org/protobuf/proto"
|
||||||
"strconv"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (ws *WsServer) SubscriberUserOnlineStatusChanges(rdb redis.UniversalClient) {
|
func (ws *WsServer) subscriberUserOnlineStatusChanges(ctx context.Context, userID string, platformIDs []int32) {
|
||||||
ctx := mcontext.SetOperationID(context.Background(), cachekey.OnlineChannel+strconv.FormatUint(rand.Uint64(), 10))
|
|
||||||
for message := range rdb.Subscribe(ctx, cachekey.OnlineChannel).Channel() {
|
|
||||||
userID, platformIDs, err := useronline.ParseUserOnlineStatus(message.Payload)
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, "OnlineCache redis subscribe parseUserOnlineStatus", err, "payload", message.Payload, "channel", message.Channel)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if ws.clients.RecvSubChange(userID, platformIDs) {
|
if ws.clients.RecvSubChange(userID, platformIDs) {
|
||||||
log.ZDebug(ctx, "gateway receive subscription message and go back online", "userID", userID, "platformIDs", platformIDs)
|
log.ZDebug(ctx, "gateway receive subscription message and go back online", "userID", userID, "platformIDs", platformIDs)
|
||||||
} else {
|
} else {
|
||||||
log.ZDebug(ctx, "gateway ignore user online status changes", "userID", userID, "platformIDs", platformIDs)
|
log.ZDebug(ctx, "gateway ignore user online status changes", "userID", userID, "platformIDs", platformIDs)
|
||||||
}
|
}
|
||||||
|
ws.pushUserIDOnlineStatus(ctx, userID, platformIDs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *WsServer) SubUserOnlineStatus(ctx context.Context, client *Client, data *Req) ([]byte, error) {
|
||||||
|
var sub sdkws.SubUserOnlineStatus
|
||||||
|
if err := proto.Unmarshal(data.Data, &sub); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ws.subscription.Sub(client, sub.SubscribeUserID, sub.UnsubscribeUserID)
|
||||||
|
var resp sdkws.SubUserOnlineStatusTips
|
||||||
|
if len(sub.SubscribeUserID) > 0 {
|
||||||
|
resp.Subscribers = make([]*sdkws.SubUserOnlineStatusElem, 0, len(sub.SubscribeUserID))
|
||||||
|
for _, userID := range sub.SubscribeUserID {
|
||||||
|
platformIDs, err := ws.online.GetUserOnlinePlatform(ctx, userID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp.Subscribers = append(resp.Subscribers, &sdkws.SubUserOnlineStatusElem{
|
||||||
|
UserID: userID,
|
||||||
|
OnlinePlatformIDs: platformIDs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return proto.Marshal(&resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
type subClient struct {
|
||||||
|
clients map[string]*Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSubscription() *Subscription {
|
||||||
|
return &Subscription{
|
||||||
|
userIDs: make(map[string]*subClient),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//import (
|
type Subscription struct {
|
||||||
// "context"
|
lock sync.RWMutex
|
||||||
// "encoding/json"
|
userIDs map[string]*subClient
|
||||||
// "github.com/openimsdk/protocol/constant"
|
}
|
||||||
// "github.com/openimsdk/protocol/sdkws"
|
|
||||||
// "github.com/openimsdk/tools/log"
|
func (s *Subscription) GetClient(userID string) []*Client {
|
||||||
// "github.com/openimsdk/tools/utils/datautil"
|
s.lock.RLock()
|
||||||
// "github.com/openimsdk/tools/utils/idutil"
|
defer s.lock.RUnlock()
|
||||||
// "sync"
|
cs, ok := s.userIDs[userID]
|
||||||
// "time"
|
if !ok {
|
||||||
//)
|
return nil
|
||||||
//
|
}
|
||||||
//type subClient struct {
|
clients := make([]*Client, 0, len(cs.clients))
|
||||||
// clients map[string]*Client
|
for _, client := range cs.clients {
|
||||||
//}
|
clients = append(clients, client)
|
||||||
//
|
}
|
||||||
//func newSubscription() *Subscription {
|
return clients
|
||||||
// return &Subscription{
|
}
|
||||||
// userIDs: make(map[string]*subClient),
|
|
||||||
// }
|
func (s *Subscription) DelClient(client *Client) {
|
||||||
//}
|
client.subLock.Lock()
|
||||||
//
|
userIDs := datautil.Keys(client.subUserIDs)
|
||||||
//type Subscription struct {
|
for _, userID := range userIDs {
|
||||||
// lock sync.RWMutex
|
delete(client.subUserIDs, userID)
|
||||||
// userIDs map[string]*subClient
|
}
|
||||||
//}
|
client.subLock.Unlock()
|
||||||
//
|
if len(userIDs) == 0 {
|
||||||
//func (s *Subscription) GetClient(userID string) []*Client {
|
return
|
||||||
// s.lock.RLock()
|
}
|
||||||
// defer s.lock.RUnlock()
|
addr := client.ctx.GetRemoteAddr()
|
||||||
// cs, ok := s.userIDs[userID]
|
s.lock.Lock()
|
||||||
// if !ok {
|
defer s.lock.Unlock()
|
||||||
// return nil
|
for _, userID := range userIDs {
|
||||||
// }
|
sub, ok := s.userIDs[userID]
|
||||||
// clients := make([]*Client, 0, len(cs.clients))
|
if !ok {
|
||||||
// for _, client := range cs.clients {
|
continue
|
||||||
// clients = append(clients, client)
|
}
|
||||||
// }
|
delete(sub.clients, addr)
|
||||||
// return clients
|
if len(sub.clients) == 0 {
|
||||||
//}
|
delete(s.userIDs, userID)
|
||||||
//
|
}
|
||||||
//func (s *Subscription) DelClient(client *Client) {
|
}
|
||||||
// client.subLock.Lock()
|
}
|
||||||
// userIDs := datautil.Keys(client.subUserIDs)
|
|
||||||
// for _, userID := range userIDs {
|
func (s *Subscription) Sub(client *Client, addUserIDs, delUserIDs []string) {
|
||||||
// delete(client.subUserIDs, userID)
|
if len(addUserIDs)+len(delUserIDs) == 0 {
|
||||||
// }
|
return
|
||||||
// client.subLock.Unlock()
|
}
|
||||||
// if len(userIDs) == 0 {
|
var (
|
||||||
// return
|
del = make(map[string]struct{})
|
||||||
// }
|
add = make(map[string]struct{})
|
||||||
// addr := client.ctx.GetRemoteAddr()
|
)
|
||||||
// s.lock.Lock()
|
client.subLock.Lock()
|
||||||
// defer s.lock.Unlock()
|
for _, userID := range delUserIDs {
|
||||||
// for _, userID := range userIDs {
|
if _, ok := client.subUserIDs[userID]; !ok {
|
||||||
// sub, ok := s.userIDs[userID]
|
continue
|
||||||
// if !ok {
|
}
|
||||||
// continue
|
del[userID] = struct{}{}
|
||||||
// }
|
delete(client.subUserIDs, userID)
|
||||||
// delete(sub.clients, addr)
|
}
|
||||||
// if len(sub.clients) == 0 {
|
for _, userID := range addUserIDs {
|
||||||
// delete(s.userIDs, userID)
|
delete(del, userID)
|
||||||
// }
|
if _, ok := client.subUserIDs[userID]; ok {
|
||||||
// }
|
continue
|
||||||
//}
|
}
|
||||||
//
|
client.subUserIDs[userID] = struct{}{}
|
||||||
//func (s *Subscription) Sub(client *Client, addUserIDs, delUserIDs []string) {
|
}
|
||||||
// if len(addUserIDs)+len(delUserIDs) == 0 {
|
client.subLock.Unlock()
|
||||||
// return
|
if len(del)+len(add) == 0 {
|
||||||
// }
|
return
|
||||||
// var (
|
}
|
||||||
// del = make(map[string]struct{})
|
addr := client.ctx.GetRemoteAddr()
|
||||||
// add = make(map[string]struct{})
|
s.lock.Lock()
|
||||||
// )
|
defer s.lock.Unlock()
|
||||||
// client.subLock.Lock()
|
for userID := range del {
|
||||||
// for _, userID := range delUserIDs {
|
sub, ok := s.userIDs[userID]
|
||||||
// if _, ok := client.subUserIDs[userID]; !ok {
|
if !ok {
|
||||||
// continue
|
continue
|
||||||
// }
|
}
|
||||||
// del[userID] = struct{}{}
|
delete(sub.clients, addr)
|
||||||
// delete(client.subUserIDs, userID)
|
if len(sub.clients) == 0 {
|
||||||
// }
|
delete(s.userIDs, userID)
|
||||||
// for _, userID := range addUserIDs {
|
}
|
||||||
// delete(del, userID)
|
}
|
||||||
// if _, ok := client.subUserIDs[userID]; ok {
|
for userID := range add {
|
||||||
// continue
|
sub, ok := s.userIDs[userID]
|
||||||
// }
|
if !ok {
|
||||||
// client.subUserIDs[userID] = struct{}{}
|
sub = &subClient{clients: make(map[string]*Client)}
|
||||||
// }
|
s.userIDs[userID] = sub
|
||||||
// client.subLock.Unlock()
|
}
|
||||||
// if len(del)+len(add) == 0 {
|
sub.clients[addr] = client
|
||||||
// return
|
}
|
||||||
// }
|
}
|
||||||
// addr := client.ctx.GetRemoteAddr()
|
|
||||||
// s.lock.Lock()
|
func (ws *WsServer) pushUserIDOnlineStatus(ctx context.Context, userID string, platformIDs []int32) {
|
||||||
// defer s.lock.Unlock()
|
clients := ws.subscription.GetClient(userID)
|
||||||
// for userID := range del {
|
if len(clients) == 0 {
|
||||||
// sub, ok := s.userIDs[userID]
|
return
|
||||||
// if !ok {
|
}
|
||||||
// continue
|
msgContent, err := json.Marshal(platformIDs)
|
||||||
// }
|
if err != nil {
|
||||||
// delete(sub.clients, addr)
|
log.ZError(ctx, "pushUserIDOnlineStatus json.Marshal", err)
|
||||||
// if len(sub.clients) == 0 {
|
return
|
||||||
// delete(s.userIDs, userID)
|
}
|
||||||
// }
|
now := time.Now().UnixMilli()
|
||||||
// }
|
msgID := idutil.GetMsgIDByMD5(userID)
|
||||||
// for userID := range add {
|
msg := &sdkws.MsgData{
|
||||||
// sub, ok := s.userIDs[userID]
|
SendID: userID,
|
||||||
// if !ok {
|
ClientMsgID: msgID,
|
||||||
// sub = &subClient{clients: make(map[string]*Client)}
|
ServerMsgID: msgID,
|
||||||
// s.userIDs[userID] = sub
|
SenderPlatformID: constant.AdminPlatformID,
|
||||||
// }
|
SessionType: constant.NotificationChatType,
|
||||||
// sub.clients[addr] = client
|
ContentType: constant.UserSubscribeOnlineStatusNotification,
|
||||||
// }
|
Content: msgContent,
|
||||||
//}
|
SendTime: now,
|
||||||
//
|
CreateTime: now,
|
||||||
//func (ws *WsServer) pushUserIDOnlineStatus(ctx context.Context, userID string, platformIDs []int32) {
|
}
|
||||||
// clients := ws.subscription.GetClient(userID)
|
for _, client := range clients {
|
||||||
// if len(clients) == 0 {
|
msg.RecvID = client.UserID
|
||||||
// return
|
if err := client.PushMessage(ctx, msg); err != nil {
|
||||||
// }
|
log.ZError(ctx, "UserSubscribeOnlineStatusNotification push failed", err, "userID", client.UserID, "platformID", client.PlatformID, "changeUserID", userID, "content", msgContent)
|
||||||
// msgContent, err := json.Marshal(platformIDs)
|
}
|
||||||
// if err != nil {
|
}
|
||||||
// log.ZError(ctx, "pushUserIDOnlineStatus json.Marshal", err)
|
}
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// now := time.Now().UnixMilli()
|
|
||||||
// msgID := idutil.GetMsgIDByMD5(userID)
|
|
||||||
// msg := &sdkws.MsgData{
|
|
||||||
// SendID: userID,
|
|
||||||
// ClientMsgID: msgID,
|
|
||||||
// ServerMsgID: msgID,
|
|
||||||
// SenderPlatformID: constant.AdminPlatformID,
|
|
||||||
// SessionType: constant.NotificationChatType,
|
|
||||||
// ContentType: constant.UserSubscribeOnlineStatusNotification,
|
|
||||||
// Content: msgContent,
|
|
||||||
// SendTime: now,
|
|
||||||
// CreateTime: now,
|
|
||||||
// }
|
|
||||||
// for _, client := range clients {
|
|
||||||
// msg.RecvID = client.UserID
|
|
||||||
// if err := client.PushMessage(ctx, msg); err != nil {
|
|
||||||
// log.ZError(ctx, "UserSubscribeOnlineStatusNotification push failed", err, "userID", client.UserID, "platformID", client.PlatformID, "changeUserID", userID, "content", msgContent)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|||||||
@ -75,7 +75,7 @@ func NewConsumerHandler(config *Config, offlinePusher offlinepush.OfflinePusher,
|
|||||||
consumerHandler.conversationLocalCache = rpccache.NewConversationLocalCache(consumerHandler.conversationRpcClient, &config.LocalCacheConfig, rdb)
|
consumerHandler.conversationLocalCache = rpccache.NewConversationLocalCache(consumerHandler.conversationRpcClient, &config.LocalCacheConfig, rdb)
|
||||||
consumerHandler.webhookClient = webhook.NewWebhookClient(config.WebhooksConfig.URL)
|
consumerHandler.webhookClient = webhook.NewWebhookClient(config.WebhooksConfig.URL)
|
||||||
consumerHandler.config = config
|
consumerHandler.config = config
|
||||||
consumerHandler.onlineCache = rpccache.NewOnlineCache(userRpcClient, consumerHandler.groupLocalCache, rdb)
|
consumerHandler.onlineCache = rpccache.NewOnlineCache(userRpcClient, consumerHandler.groupLocalCache, rdb, nil)
|
||||||
return &consumerHandler, nil
|
return &consumerHandler, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewOnlineCache(user rpcclient.UserRpcClient, group *GroupLocalCache, rdb redis.UniversalClient) *OnlineCache {
|
func NewOnlineCache(user rpcclient.UserRpcClient, group *GroupLocalCache, rdb redis.UniversalClient, fn func(ctx context.Context, userID string, platformIDs []int32)) *OnlineCache {
|
||||||
x := &OnlineCache{
|
x := &OnlineCache{
|
||||||
user: user,
|
user: user,
|
||||||
group: group,
|
group: group,
|
||||||
@ -33,6 +33,9 @@ func NewOnlineCache(user rpcclient.UserRpcClient, group *GroupLocalCache, rdb re
|
|||||||
}
|
}
|
||||||
storageCache := x.setUserOnline(userID, platformIDs)
|
storageCache := x.setUserOnline(userID, platformIDs)
|
||||||
log.ZDebug(ctx, "OnlineCache setUserOnline", "userID", userID, "platformIDs", platformIDs, "payload", message.Payload, "storageCache", storageCache)
|
log.ZDebug(ctx, "OnlineCache setUserOnline", "userID", userID, "platformIDs", platformIDs, "payload", message.Payload, "storageCache", storageCache)
|
||||||
|
if fn != nil {
|
||||||
|
fn(ctx, userID, platformIDs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return x
|
return x
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user