diff --git a/go.mod b/go.mod index 4eaa18ccc8..26f167a19e 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,6 @@ module github.com/openimsdk/open-im-server/v3 go 1.22.7 -toolchain go1.23.2 - require ( firebase.google.com/go/v4 v4.14.1 github.com/dtm-labs/rockscache v0.1.1 @@ -14,8 +12,8 @@ require ( github.com/gorilla/websocket v1.5.1 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/mitchellh/mapstructure v1.5.0 - github.com/openimsdk/protocol v0.0.72-alpha.66 - github.com/openimsdk/tools v0.0.50-alpha.57 + github.com/openimsdk/protocol v0.0.72-alpha.68 + github.com/openimsdk/tools v0.0.50-alpha.60 github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.18.0 github.com/stretchr/testify v1.9.0 diff --git a/go.sum b/go.sum index 6e283eb668..c0385481ca 100644 --- a/go.sum +++ b/go.sum @@ -347,10 +347,10 @@ 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/openimsdk/gomake v0.0.15-alpha.2 h1:5Q8yl8ezy2yx+q8/ucU/t4kJnDfCzNOrkXcDACCqtyM= github.com/openimsdk/gomake v0.0.15-alpha.2/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI= -github.com/openimsdk/protocol v0.0.72-alpha.66 h1:5KoDY6M4T+pXg449ScF6hqeQ+WenBwNyUJn/t8W0oBQ= -github.com/openimsdk/protocol v0.0.72-alpha.66/go.mod h1:Iet+piS/jaS+kWWyj6EEr36mk4ISzIRYjoMSVA4dq2M= -github.com/openimsdk/tools v0.0.50-alpha.57 h1:oIKV6vYhqp7TRmZ6Pe+r9RNl1D5s7aB/kE9yQVEWcSY= -github.com/openimsdk/tools v0.0.50-alpha.57/go.mod h1:muCtxguNJv8lFwLei27UASu2Nvg4ERSeN0R4K5tivk0= +github.com/openimsdk/protocol v0.0.72-alpha.68 h1:Ekn6S9Ftt12Xs/p9kJ39RDr2gSwIczz+MmSHQE4lAek= +github.com/openimsdk/protocol v0.0.72-alpha.68/go.mod h1:Iet+piS/jaS+kWWyj6EEr36mk4ISzIRYjoMSVA4dq2M= +github.com/openimsdk/tools v0.0.50-alpha.60 h1:dYqYpSdSN5o6CxlEjua2USfwfUiG0tUWFBpqghTjbWE= +github.com/openimsdk/tools v0.0.50-alpha.60/go.mod h1:muCtxguNJv8lFwLei27UASu2Nvg4ERSeN0R4K5tivk0= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= diff --git a/internal/api/auth.go b/internal/api/auth.go index c7e7ff7046..92d911b712 100644 --- a/internal/api/auth.go +++ b/internal/api/auth.go @@ -20,24 +20,26 @@ import ( "github.com/openimsdk/tools/a2r" ) -type AuthApi struct{} +type AuthApi struct { + Client auth.AuthClient +} -func NewAuthApi() AuthApi { - return AuthApi{} +func NewAuthApi(client auth.AuthClient) AuthApi { + return AuthApi{client} } func (o *AuthApi) GetAdminToken(c *gin.Context) { - a2r.CallV2(c, auth.GetAdminTokenCaller.Invoke) + a2r.Call(c, auth.AuthClient.GetAdminToken, o.Client) } func (o *AuthApi) GetUserToken(c *gin.Context) { - a2r.CallV2(c, auth.GetUserTokenCaller.Invoke) + a2r.Call(c, auth.AuthClient.GetUserToken, o.Client) } func (o *AuthApi) ParseToken(c *gin.Context) { - a2r.CallV2(c, auth.ParseTokenCaller.Invoke) + a2r.Call(c, auth.AuthClient.ParseToken, o.Client) } func (o *AuthApi) ForceLogout(c *gin.Context) { - a2r.CallV2(c, auth.ForceLogoutCaller.Invoke) + a2r.Call(c, auth.AuthClient.ForceLogout, o.Client) } diff --git a/internal/api/conversation.go b/internal/api/conversation.go index 4004944e55..f7dbc133c1 100644 --- a/internal/api/conversation.go +++ b/internal/api/conversation.go @@ -20,52 +20,54 @@ import ( "github.com/openimsdk/tools/a2r" ) -type ConversationApi struct{} +type ConversationApi struct { + Client conversation.ConversationClient +} -func NewConversationApi() ConversationApi { - return ConversationApi{} +func NewConversationApi(client conversation.ConversationClient) ConversationApi { + return ConversationApi{client} } func (o *ConversationApi) GetAllConversations(c *gin.Context) { - a2r.CallV2(c, conversation.GetAllConversationsCaller.Invoke) + a2r.Call(c, conversation.ConversationClient.GetAllConversations, o.Client) } func (o *ConversationApi) GetSortedConversationList(c *gin.Context) { - a2r.CallV2(c, conversation.GetSortedConversationListCaller.Invoke) + a2r.Call(c, conversation.ConversationClient.GetSortedConversationList, o.Client) } func (o *ConversationApi) GetConversation(c *gin.Context) { - a2r.CallV2(c, conversation.GetConversationCaller.Invoke) + a2r.Call(c, conversation.ConversationClient.GetConversation, o.Client) } func (o *ConversationApi) GetConversations(c *gin.Context) { - a2r.CallV2(c, conversation.GetConversationsCaller.Invoke) + a2r.Call(c, conversation.ConversationClient.GetConversations, o.Client) } func (o *ConversationApi) SetConversations(c *gin.Context) { - a2r.CallV2(c, conversation.SetConversationsCaller.Invoke) + a2r.Call(c, conversation.ConversationClient.SetConversations, o.Client) } func (o *ConversationApi) GetConversationOfflinePushUserIDs(c *gin.Context) { - a2r.CallV2(c, conversation.GetConversationOfflinePushUserIDsCaller.Invoke) + a2r.Call(c, conversation.ConversationClient.GetConversationOfflinePushUserIDs, o.Client) } func (o *ConversationApi) GetFullOwnerConversationIDs(c *gin.Context) { - a2r.CallV2(c, conversation.GetFullOwnerConversationIDsCaller.Invoke) + a2r.Call(c, conversation.ConversationClient.GetFullOwnerConversationIDs, o.Client) } func (o *ConversationApi) GetIncrementalConversation(c *gin.Context) { - a2r.CallV2(c, conversation.GetIncrementalConversationCaller.Invoke) + a2r.Call(c, conversation.ConversationClient.GetIncrementalConversation, o.Client) } func (o *ConversationApi) GetOwnerConversation(c *gin.Context) { - a2r.CallV2(c, conversation.GetOwnerConversationCaller.Invoke) + a2r.Call(c, conversation.ConversationClient.GetOwnerConversation, o.Client) } func (o *ConversationApi) GetNotNotifyConversationIDs(c *gin.Context) { - a2r.CallV2(c, conversation.GetNotNotifyConversationIDsCaller.Invoke) + a2r.Call(c, conversation.ConversationClient.GetNotNotifyConversationIDs, o.Client) } func (o *ConversationApi) GetPinnedConversationIDs(c *gin.Context) { - a2r.CallV2(c, conversation.GetPinnedConversationIDsCaller.Invoke) + a2r.Call(c, conversation.ConversationClient.GetPinnedConversationIDs, o.Client) } diff --git a/internal/api/friend.go b/internal/api/friend.go index 4e08474fbf..7d84ff0dca 100644 --- a/internal/api/friend.go +++ b/internal/api/friend.go @@ -21,94 +21,96 @@ import ( "github.com/openimsdk/tools/a2r" ) -type FriendApi struct{} +type FriendApi struct { + Client relation.FriendClient +} -func NewFriendApi() FriendApi { - return FriendApi{} +func NewFriendApi(client relation.FriendClient) FriendApi { + return FriendApi{client} } func (o *FriendApi) ApplyToAddFriend(c *gin.Context) { - a2r.CallV2(c, relation.ApplyToAddFriendCaller.Invoke) + a2r.Call(c, relation.FriendClient.ApplyToAddFriend, o.Client) } func (o *FriendApi) RespondFriendApply(c *gin.Context) { - a2r.CallV2(c, relation.RespondFriendApplyCaller.Invoke) + a2r.Call(c, relation.FriendClient.RespondFriendApply, o.Client) } func (o *FriendApi) DeleteFriend(c *gin.Context) { - a2r.CallV2(c, relation.DeleteFriendCaller.Invoke) + a2r.Call(c, relation.FriendClient.DeleteFriend, o.Client) } func (o *FriendApi) GetFriendApplyList(c *gin.Context) { - a2r.CallV2(c, relation.GetPaginationFriendsApplyToCaller.Invoke) + a2r.Call(c, relation.FriendClient.GetPaginationFriendsApplyTo, o.Client) } func (o *FriendApi) GetDesignatedFriendsApply(c *gin.Context) { - a2r.CallV2(c, relation.GetDesignatedFriendsApplyCaller.Invoke) + a2r.Call(c, relation.FriendClient.GetDesignatedFriendsApply, o.Client) } func (o *FriendApi) GetSelfApplyList(c *gin.Context) { - a2r.CallV2(c, relation.GetPaginationFriendsApplyFromCaller.Invoke) + a2r.Call(c, relation.FriendClient.GetPaginationFriendsApplyFrom, o.Client) } func (o *FriendApi) GetFriendList(c *gin.Context) { - a2r.CallV2(c, relation.GetPaginationFriendsCaller.Invoke) + a2r.Call(c, relation.FriendClient.GetPaginationFriends, o.Client) } func (o *FriendApi) GetDesignatedFriends(c *gin.Context) { - a2r.CallV2(c, relation.GetDesignatedFriendsCaller.Invoke) + a2r.Call(c, relation.FriendClient.GetDesignatedFriends, o.Client) } func (o *FriendApi) SetFriendRemark(c *gin.Context) { - a2r.CallV2(c, relation.SetFriendRemarkCaller.Invoke) + a2r.Call(c, relation.FriendClient.SetFriendRemark, o.Client) } func (o *FriendApi) AddBlack(c *gin.Context) { - a2r.CallV2(c, relation.AddBlackCaller.Invoke) + a2r.Call(c, relation.FriendClient.AddBlack, o.Client) } func (o *FriendApi) GetPaginationBlacks(c *gin.Context) { - a2r.CallV2(c, relation.GetPaginationBlacksCaller.Invoke) + a2r.Call(c, relation.FriendClient.GetPaginationBlacks, o.Client) } func (o *FriendApi) GetSpecifiedBlacks(c *gin.Context) { - a2r.CallV2(c, relation.GetSpecifiedBlacksCaller.Invoke) + a2r.Call(c, relation.FriendClient.GetSpecifiedBlacks, o.Client) } func (o *FriendApi) RemoveBlack(c *gin.Context) { - a2r.CallV2(c, relation.RemoveBlackCaller.Invoke) + a2r.Call(c, relation.FriendClient.RemoveBlack, o.Client) } func (o *FriendApi) ImportFriends(c *gin.Context) { - a2r.CallV2(c, relation.ImportFriendsCaller.Invoke) + a2r.Call(c, relation.FriendClient.ImportFriends, o.Client) } func (o *FriendApi) IsFriend(c *gin.Context) { - a2r.CallV2(c, relation.IsFriendCaller.Invoke) + a2r.Call(c, relation.FriendClient.IsFriend, o.Client) } func (o *FriendApi) GetFriendIDs(c *gin.Context) { - a2r.CallV2(c, relation.GetFriendIDsCaller.Invoke) + a2r.Call(c, relation.FriendClient.GetFriendIDs, o.Client) } func (o *FriendApi) GetSpecifiedFriendsInfo(c *gin.Context) { - a2r.CallV2(c, relation.GetSpecifiedFriendsInfoCaller.Invoke) + a2r.Call(c, relation.FriendClient.GetSpecifiedFriendsInfo, o.Client) } func (o *FriendApi) UpdateFriends(c *gin.Context) { - a2r.CallV2(c, relation.UpdateFriendsCaller.Invoke) + a2r.Call(c, relation.FriendClient.UpdateFriends, o.Client) } func (o *FriendApi) GetIncrementalFriends(c *gin.Context) { - a2r.CallV2(c, relation.GetIncrementalFriendsCaller.Invoke) + a2r.Call(c, relation.FriendClient.GetIncrementalFriends, o.Client) } // GetIncrementalBlacks is temporarily unused. // Deprecated: This function is currently unused and may be removed in future versions. func (o *FriendApi) GetIncrementalBlacks(c *gin.Context) { - a2r.CallV2(c, relation.GetIncrementalBlacksCaller.Invoke) + a2r.Call(c, relation.FriendClient.GetIncrementalBlacks, o.Client) } func (o *FriendApi) GetFullFriendUserIDs(c *gin.Context) { - a2r.CallV2(c, relation.GetFullFriendUserIDsCaller.Invoke) + a2r.Call(c, relation.FriendClient.GetFullFriendUserIDs, o.Client) } diff --git a/internal/api/group.go b/internal/api/group.go index 784197fd81..97b6b73f05 100644 --- a/internal/api/group.go +++ b/internal/api/group.go @@ -20,146 +20,148 @@ import ( "github.com/openimsdk/tools/a2r" ) -type GroupApi struct{} +type GroupApi struct { + Client group.GroupClient +} -func NewGroupApi() GroupApi { - return GroupApi{} +func NewGroupApi(client group.GroupClient) GroupApi { + return GroupApi{client} } func (o *GroupApi) CreateGroup(c *gin.Context) { - a2r.CallV2(c, group.CreateGroupCaller.Invoke) + a2r.Call(c, group.GroupClient.CreateGroup, o.Client) } func (o *GroupApi) SetGroupInfo(c *gin.Context) { - a2r.CallV2(c, group.SetGroupInfoCaller.Invoke) + a2r.Call(c, group.GroupClient.SetGroupInfo, o.Client) } func (o *GroupApi) SetGroupInfoEx(c *gin.Context) { - a2r.CallV2(c, group.SetGroupInfoExCaller.Invoke) + a2r.Call(c, group.GroupClient.SetGroupInfoEx, o.Client) } func (o *GroupApi) JoinGroup(c *gin.Context) { - a2r.CallV2(c, group.JoinGroupCaller.Invoke) + a2r.Call(c, group.GroupClient.JoinGroup, o.Client) } func (o *GroupApi) QuitGroup(c *gin.Context) { - a2r.CallV2(c, group.QuitGroupCaller.Invoke) + a2r.Call(c, group.GroupClient.QuitGroup, o.Client) } func (o *GroupApi) ApplicationGroupResponse(c *gin.Context) { - a2r.CallV2(c, group.GroupApplicationResponseCaller.Invoke) + a2r.Call(c, group.GroupClient.GroupApplicationResponse, o.Client) } func (o *GroupApi) TransferGroupOwner(c *gin.Context) { - a2r.CallV2(c, group.TransferGroupOwnerCaller.Invoke) + a2r.Call(c, group.GroupClient.TransferGroupOwner, o.Client) } func (o *GroupApi) GetRecvGroupApplicationList(c *gin.Context) { - a2r.CallV2(c, group.GetGroupApplicationListCaller.Invoke) + a2r.Call(c, group.GroupClient.GetGroupApplicationList, o.Client) } func (o *GroupApi) GetUserReqGroupApplicationList(c *gin.Context) { - a2r.CallV2(c, group.GetUserReqApplicationListCaller.Invoke) + a2r.Call(c, group.GroupClient.GetUserReqApplicationList, o.Client) } func (o *GroupApi) GetGroupUsersReqApplicationList(c *gin.Context) { - a2r.CallV2(c, group.GetGroupUsersReqApplicationListCaller.Invoke) + a2r.Call(c, group.GroupClient.GetGroupUsersReqApplicationList, o.Client) } func (o *GroupApi) GetSpecifiedUserGroupRequestInfo(c *gin.Context) { - a2r.CallV2(c, group.GetSpecifiedUserGroupRequestInfoCaller.Invoke) + a2r.Call(c, group.GroupClient.GetSpecifiedUserGroupRequestInfo, o.Client) } func (o *GroupApi) GetGroupsInfo(c *gin.Context) { - a2r.CallV2(c, group.GetGroupsInfoCaller.Invoke) - //a2r.Call(group.GroupClient.GetGroupsInfo, o.Client, c, a2r.NewNilReplaceOption(group.GroupClient.GetGroupsInfo)) + a2r.Call(c, group.GroupClient.GetGroupsInfo, o.Client) + //a2r.Call(c, group.GroupClient.GetGroupsInfo, o.Client, c, a2r.NewNilReplaceOption(group.GroupClient.GetGroupsInfo)) } func (o *GroupApi) KickGroupMember(c *gin.Context) { - a2r.CallV2(c, group.KickGroupMemberCaller.Invoke) + a2r.Call(c, group.GroupClient.KickGroupMember, o.Client) } func (o *GroupApi) GetGroupMembersInfo(c *gin.Context) { - a2r.CallV2(c, group.GetGroupMembersInfoCaller.Invoke) - //a2r.Call(group.GroupClient.GetGroupMembersInfo, o.Client, c, a2r.NewNilReplaceOption(group.GroupClient.GetGroupMembersInfo)) + a2r.Call(c, group.GroupClient.GetGroupMembersInfo, o.Client) + //a2r.Call(c, group.GroupClient.GetGroupMembersInfo, o.Client, c, a2r.NewNilReplaceOption(group.GroupClient.GetGroupMembersInfo)) } func (o *GroupApi) GetGroupMemberList(c *gin.Context) { - a2r.CallV2(c, group.GetGroupMemberListCaller.Invoke) + a2r.Call(c, group.GroupClient.GetGroupMemberList, o.Client) } func (o *GroupApi) InviteUserToGroup(c *gin.Context) { - a2r.CallV2(c, group.InviteUserToGroupCaller.Invoke) + a2r.Call(c, group.GroupClient.InviteUserToGroup, o.Client) } func (o *GroupApi) GetJoinedGroupList(c *gin.Context) { - a2r.CallV2(c, group.GetJoinedGroupListCaller.Invoke) + a2r.Call(c, group.GroupClient.GetJoinedGroupList, o.Client) } func (o *GroupApi) DismissGroup(c *gin.Context) { - a2r.CallV2(c, group.DismissGroupCaller.Invoke) + a2r.Call(c, group.GroupClient.DismissGroup, o.Client) } func (o *GroupApi) MuteGroupMember(c *gin.Context) { - a2r.CallV2(c, group.MuteGroupMemberCaller.Invoke) + a2r.Call(c, group.GroupClient.MuteGroupMember, o.Client) } func (o *GroupApi) CancelMuteGroupMember(c *gin.Context) { - a2r.CallV2(c, group.CancelMuteGroupMemberCaller.Invoke) + a2r.Call(c, group.GroupClient.CancelMuteGroupMember, o.Client) } func (o *GroupApi) MuteGroup(c *gin.Context) { - a2r.CallV2(c, group.MuteGroupCaller.Invoke) + a2r.Call(c, group.GroupClient.MuteGroup, o.Client) } func (o *GroupApi) CancelMuteGroup(c *gin.Context) { - a2r.CallV2(c, group.CancelMuteGroupCaller.Invoke) + a2r.Call(c, group.GroupClient.CancelMuteGroup, o.Client) } func (o *GroupApi) SetGroupMemberInfo(c *gin.Context) { - a2r.CallV2(c, group.SetGroupMemberInfoCaller.Invoke) + a2r.Call(c, group.GroupClient.SetGroupMemberInfo, o.Client) } func (o *GroupApi) GetGroupAbstractInfo(c *gin.Context) { - a2r.CallV2(c, group.GetGroupAbstractInfoCaller.Invoke) + a2r.Call(c, group.GroupClient.GetGroupAbstractInfo, o.Client) } // func (g *Group) SetGroupMemberNickname(c *gin.Context) { -// a2r.Call(group.GroupClient.SetGroupMemberNickname, g.userClient, c) +// a2r.Call(c, group.GroupClient.SetGroupMemberNickname, g.userClient) //} // // func (g *Group) GetGroupAllMemberList(c *gin.Context) { -// a2r.Call(group.GroupClient.GetGroupAllMember, g.userClient, c) +// a2r.Call(c, group.GroupClient.GetGroupAllMember, g.userClient) //} func (o *GroupApi) GroupCreateCount(c *gin.Context) { - a2r.CallV2(c, group.GroupCreateCountCaller.Invoke) + a2r.Call(c, group.GroupClient.GroupCreateCount, o.Client) } func (o *GroupApi) GetGroups(c *gin.Context) { - a2r.CallV2(c, group.GetGroupsCaller.Invoke) + a2r.Call(c, group.GroupClient.GetGroups, o.Client) } func (o *GroupApi) GetGroupMemberUserIDs(c *gin.Context) { - a2r.CallV2(c, group.GetGroupMemberUserIDsCaller.Invoke) + a2r.Call(c, group.GroupClient.GetGroupMemberUserIDs, o.Client) } func (o *GroupApi) GetIncrementalJoinGroup(c *gin.Context) { - a2r.CallV2(c, group.GetIncrementalJoinGroupCaller.Invoke) + a2r.Call(c, group.GroupClient.GetIncrementalJoinGroup, o.Client) } func (o *GroupApi) GetIncrementalGroupMember(c *gin.Context) { - a2r.CallV2(c, group.GetIncrementalGroupMemberCaller.Invoke) + a2r.Call(c, group.GroupClient.GetIncrementalGroupMember, o.Client) } func (o *GroupApi) GetIncrementalGroupMemberBatch(c *gin.Context) { - a2r.CallV2(c, group.BatchGetIncrementalGroupMemberCaller.Invoke) + a2r.Call(c, group.GroupClient.BatchGetIncrementalGroupMember, o.Client) } func (o *GroupApi) GetFullGroupMemberUserIDs(c *gin.Context) { - a2r.CallV2(c, group.GetFullGroupMemberUserIDsCaller.Invoke) + a2r.Call(c, group.GroupClient.GetFullGroupMemberUserIDs, o.Client) } func (o *GroupApi) GetFullJoinGroupIDs(c *gin.Context) { - a2r.CallV2(c, group.GetFullJoinGroupIDsCaller.Invoke) + a2r.Call(c, group.GroupClient.GetFullJoinGroupIDs, o.Client) } diff --git a/internal/api/init.go b/internal/api/init.go index 53a0aed7b1..33652aca5d 100644 --- a/internal/api/init.go +++ b/internal/api/init.go @@ -30,7 +30,6 @@ import ( kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discovery" disetcd "github.com/openimsdk/open-im-server/v3/pkg/common/discovery/etcd" "github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/tools/discovery/etcd" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" @@ -40,7 +39,6 @@ import ( "github.com/openimsdk/tools/utils/jsonutil" "github.com/openimsdk/tools/utils/network" "github.com/openimsdk/tools/utils/runtimeenv" - clientv3 "go.etcd.io/etcd/client/v3" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) @@ -65,9 +63,6 @@ func Start(ctx context.Context, index int, config *Config) error { return errs.WrapMsg(err, "failed to register discovery service") } client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin"))) - if err = rpcclient.InitRpcCaller(client, config.Discovery.RpcService); err != nil { - return err - } var ( netDone = make(chan struct{}, 1) @@ -95,11 +90,10 @@ func Start(ctx context.Context, index int, config *Config) error { return errs.New("only etcd support autoSetPorts", "RegisterName", "api").Wrap() } - var etcdClient *clientv3.Client - if config.Discovery.Enable == conf.ETCD { - etcdClient = client.(*etcd.SvcDiscoveryRegistryImpl).GetClient() + router, err := newGinRouter(ctx, client, config) + if err != nil { + return err } - router := newGinRouter(client, config, etcdClient) if config.API.Prometheus.Enable { var ( listener net.Listener @@ -111,6 +105,8 @@ func Start(ctx context.Context, index int, config *Config) error { return err } + etcdClient := client.(*etcd.SvcDiscoveryRegistryImpl).GetClient() + _, err = etcdClient.Put(ctx, prommetrics.BuildDiscoveryKey(prommetrics.APIKeyName), jsonutil.StructToJsonString(prommetrics.BuildDefaultTarget(registerIP, prometheusPort))) if err != nil { return errs.WrapMsg(err, "etcd put err") diff --git a/internal/api/jssdk/jssdk.go b/internal/api/jssdk/jssdk.go index 409fcbf79d..036cb027ab 100644 --- a/internal/api/jssdk/jssdk.go +++ b/internal/api/jssdk/jssdk.go @@ -2,16 +2,15 @@ package jssdk import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "sort" "github.com/gin-gonic/gin" "github.com/openimsdk/protocol/conversation" - "github.com/openimsdk/protocol/group" "github.com/openimsdk/protocol/jssdk" "github.com/openimsdk/protocol/msg" "github.com/openimsdk/protocol/relation" "github.com/openimsdk/protocol/sdkws" - "github.com/openimsdk/protocol/user" "github.com/openimsdk/tools/mcontext" "github.com/openimsdk/tools/utils/datautil" ) @@ -26,6 +25,11 @@ func NewJSSdkApi() *JSSdk { } type JSSdk struct { + userClient rpcli.UserClient + relationClient rpcli.RelationClient + groupClient rpcli.GroupClient + conversationClient rpcli.ConversationClient + msgClient rpcli.MsgClient } func (x *JSSdk) GetActiveConversations(c *gin.Context) { @@ -57,11 +61,11 @@ func (x *JSSdk) fillConversations(ctx context.Context, conversations []*jssdk.Co groupMap map[string]*sdkws.GroupInfo ) if len(userIDs) > 0 { - users, err := field(ctx, user.GetDesignateUsersCaller.Invoke, &user.GetDesignateUsersReq{UserIDs: userIDs}, (*user.GetDesignateUsersResp).GetUsersInfo) + users, err := x.userClient.GetUsersInfo(ctx, userIDs) if err != nil { return err } - friends, err := field(ctx, relation.GetFriendInfoCaller.Invoke, &relation.GetFriendInfoReq{OwnerUserID: conversations[0].Conversation.OwnerUserID, FriendUserIDs: userIDs}, (*relation.GetFriendInfoResp).GetFriendInfos) + friends, err := x.relationClient.GetFriendsInfo(ctx, conversations[0].Conversation.OwnerUserID, userIDs) if err != nil { return err } @@ -69,11 +73,11 @@ func (x *JSSdk) fillConversations(ctx context.Context, conversations []*jssdk.Co friendMap = datautil.SliceToMap(friends, (*relation.FriendInfoOnly).GetFriendUserID) } if len(groupIDs) > 0 { - resp, err := group.GetGroupsInfoCaller.Invoke(ctx, &group.GetGroupsInfoReq{GroupIDs: groupIDs}) + groups, err := x.groupClient.GetGroupsInfo(ctx, groupIDs) if err != nil { return err } - groupMap = datautil.SliceToMap(resp.GroupInfos, (*sdkws.GroupInfo).GetGroupID) + groupMap = datautil.SliceToMap(groups, (*sdkws.GroupInfo).GetGroupID) } for _, c := range conversations { if c.Conversation.GroupID == "" { @@ -91,21 +95,18 @@ func (x *JSSdk) getActiveConversations(ctx context.Context, req *jssdk.GetActive req.Count = defaultGetActiveConversation } req.OwnerUserID = mcontext.GetOpUserID(ctx) - conversationIDs, err := field(ctx, conversation.GetConversationIDsCaller.Invoke, - &conversation.GetConversationIDsReq{UserID: req.OwnerUserID}, (*conversation.GetConversationIDsResp).GetConversationIDs) + conversationIDs, err := x.conversationClient.GetConversationIDs(ctx, req.OwnerUserID) if err != nil { return nil, err } if len(conversationIDs) == 0 { return &jssdk.GetActiveConversationsResp{}, nil } - readSeq, err := field(ctx, msg.GetHasReadSeqsCaller.Invoke, - &msg.GetHasReadSeqsReq{UserID: req.OwnerUserID, ConversationIDs: conversationIDs}, (*msg.SeqsInfoResp).GetMaxSeqs) + readSeq, err := x.msgClient.GetHasReadSeqs(ctx, conversationIDs, req.OwnerUserID) if err != nil { return nil, err } - activeConversation, err := field(ctx, msg.GetActiveConversationCaller.Invoke, - &msg.GetActiveConversationReq{ConversationIDs: conversationIDs}, (*msg.GetActiveConversationResp).GetConversations) + activeConversation, err := x.msgClient.GetActiveConversation(ctx, conversationIDs) if err != nil { return nil, err } @@ -116,8 +117,7 @@ func (x *JSSdk) getActiveConversations(ctx context.Context, req *jssdk.GetActive Conversation: activeConversation, } if len(activeConversation) > 1 { - pinnedConversationIDs, err := field(ctx, conversation.GetPinnedConversationIDsCaller.Invoke, - &conversation.GetPinnedConversationIDsReq{UserID: req.OwnerUserID}, (*conversation.GetPinnedConversationIDsResp).GetConversationIDs) + pinnedConversationIDs, err := x.conversationClient.GetPinnedConversationIDs(ctx, req.OwnerUserID) if err != nil { return nil, err } @@ -125,25 +125,18 @@ func (x *JSSdk) getActiveConversations(ctx context.Context, req *jssdk.GetActive } sort.Sort(&sortConversations) sortList := sortConversations.Top(int(req.Count)) - conversations, err := field(ctx, conversation.GetConversationsCaller.Invoke, - &conversation.GetConversationsReq{ - OwnerUserID: req.OwnerUserID, - ConversationIDs: datautil.Slice(sortList, func(c *msg.ActiveConversation) string { - return c.ConversationID - })}, (*conversation.GetConversationsResp).GetConversations) + conversations, err := x.conversationClient.GetConversations(ctx, datautil.Slice(sortList, func(c *msg.ActiveConversation) string { + return c.ConversationID + }), req.OwnerUserID) if err != nil { return nil, err } - msgs, err := field(ctx, msg.GetSeqMessageCaller.Invoke, - &msg.GetSeqMessageReq{ - UserID: req.OwnerUserID, - Conversations: datautil.Slice(sortList, func(c *msg.ActiveConversation) *msg.ConversationSeqs { - return &msg.ConversationSeqs{ - ConversationID: c.ConversationID, - Seqs: []int64{c.MaxSeq}, - } - }), - }, (*msg.GetSeqMessageResp).GetMsgs) + msgs, err := x.msgClient.GetSeqMessage(ctx, req.OwnerUserID, datautil.Slice(sortList, func(c *msg.ActiveConversation) *msg.ConversationSeqs { + return &msg.ConversationSeqs{ + ConversationID: c.ConversationID, + Seqs: []int64{c.MaxSeq}, + } + })) if err != nil { return nil, err } @@ -185,7 +178,7 @@ func (x *JSSdk) getActiveConversations(ctx context.Context, req *jssdk.GetActive func (x *JSSdk) getConversations(ctx context.Context, req *jssdk.GetConversationsReq) (*jssdk.GetConversationsResp, error) { req.OwnerUserID = mcontext.GetOpUserID(ctx) - conversations, err := field(ctx, conversation.GetConversationsCaller.Invoke, &conversation.GetConversationsReq{OwnerUserID: req.OwnerUserID, ConversationIDs: req.ConversationIDs}, (*conversation.GetConversationsResp).GetConversations) + conversations, err := x.conversationClient.GetConversations(ctx, req.ConversationIDs, req.OwnerUserID) if err != nil { return nil, err } @@ -195,13 +188,11 @@ func (x *JSSdk) getConversations(ctx context.Context, req *jssdk.GetConversation req.ConversationIDs = datautil.Slice(conversations, func(c *conversation.Conversation) string { return c.ConversationID }) - maxSeqs, err := field(ctx, msg.GetMaxSeqsCaller.Invoke, - &msg.GetMaxSeqsReq{ConversationIDs: req.ConversationIDs}, (*msg.SeqsInfoResp).GetMaxSeqs) + maxSeqs, err := x.msgClient.GetMaxSeqs(ctx, req.ConversationIDs) if err != nil { return nil, err } - readSeqs, err := field(ctx, msg.GetHasReadSeqsCaller.Invoke, - &msg.GetHasReadSeqsReq{UserID: req.OwnerUserID, ConversationIDs: req.ConversationIDs}, (*msg.SeqsInfoResp).GetMaxSeqs) + readSeqs, err := x.msgClient.GetHasReadSeqs(ctx, req.ConversationIDs, req.OwnerUserID) if err != nil { return nil, err } @@ -216,8 +207,7 @@ func (x *JSSdk) getConversations(ctx context.Context, req *jssdk.GetConversation } var msgs map[string]*sdkws.PullMsgs if len(conversationSeqs) > 0 { - msgs, err = field(ctx, msg.GetSeqMessageCaller.Invoke, - &msg.GetSeqMessageReq{UserID: req.OwnerUserID, Conversations: conversationSeqs}, (*msg.GetSeqMessageResp).GetMsgs) + msgs, err = x.msgClient.GetSeqMessage(ctx, req.OwnerUserID, conversationSeqs) if err != nil { return nil, err } diff --git a/internal/api/msg.go b/internal/api/msg.go index 8efd348949..fc235354c7 100644 --- a/internal/api/msg.go +++ b/internal/api/msg.go @@ -21,11 +21,10 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/apistruct" "github.com/openimsdk/open-im-server/v3/pkg/authverify" "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/msg" - "github.com/openimsdk/protocol/rpccall" "github.com/openimsdk/protocol/sdkws" - "github.com/openimsdk/protocol/user" "github.com/openimsdk/tools/a2r" "github.com/openimsdk/tools/apiresp" "github.com/openimsdk/tools/errs" @@ -38,12 +37,14 @@ import ( ) type MessageApi struct { - validate *validator.Validate + Client msg.MsgClient + userClient *rpcli.UserClient imAdminUserID []string + validate *validator.Validate } -func NewMessageApi(imAdminUserID []string) MessageApi { - return MessageApi{validate: validator.New(), imAdminUserID: imAdminUserID} +func NewMessageApi(client msg.MsgClient, userClient *rpcli.UserClient, imAdminUserID []string) MessageApi { + return MessageApi{Client: client, userClient: userClient, imAdminUserID: imAdminUserID, validate: validator.New()} } func (*MessageApi) SetOptions(options map[string]bool, value bool) { @@ -105,51 +106,51 @@ func (m *MessageApi) newUserSendMsgReq(_ *gin.Context, params *apistruct.SendMsg } func (m *MessageApi) GetSeq(c *gin.Context) { - a2r.CallV2(c, msg.GetMaxSeqCaller.Invoke) + a2r.Call(c, msg.MsgClient.GetMaxSeq, m.Client) } func (m *MessageApi) PullMsgBySeqs(c *gin.Context) { - a2r.CallV2(c, msg.PullMessageBySeqsCaller.Invoke) + a2r.Call(c, msg.MsgClient.PullMessageBySeqs, m.Client) } func (m *MessageApi) RevokeMsg(c *gin.Context) { - a2r.CallV2(c, msg.RevokeMsgCaller.Invoke) + a2r.Call(c, msg.MsgClient.RevokeMsg, m.Client) } func (m *MessageApi) MarkMsgsAsRead(c *gin.Context) { - a2r.CallV2(c, msg.MarkMsgsAsReadCaller.Invoke) + a2r.Call(c, msg.MsgClient.MarkMsgsAsRead, m.Client) } func (m *MessageApi) MarkConversationAsRead(c *gin.Context) { - a2r.CallV2(c, msg.MarkConversationAsReadCaller.Invoke) + a2r.Call(c, msg.MsgClient.MarkConversationAsRead, m.Client) } func (m *MessageApi) GetConversationsHasReadAndMaxSeq(c *gin.Context) { - a2r.CallV2(c, msg.GetConversationsHasReadAndMaxSeqCaller.Invoke) + a2r.Call(c, msg.MsgClient.GetConversationsHasReadAndMaxSeq, m.Client) } func (m *MessageApi) SetConversationHasReadSeq(c *gin.Context) { - a2r.CallV2(c, msg.SetConversationHasReadSeqCaller.Invoke) + a2r.Call(c, msg.MsgClient.SetConversationHasReadSeq, m.Client) } func (m *MessageApi) ClearConversationsMsg(c *gin.Context) { - a2r.CallV2(c, msg.ClearConversationsMsgCaller.Invoke) + a2r.Call(c, msg.MsgClient.ClearConversationsMsg, m.Client) } func (m *MessageApi) UserClearAllMsg(c *gin.Context) { - a2r.CallV2(c, msg.UserClearAllMsgCaller.Invoke) + a2r.Call(c, msg.MsgClient.UserClearAllMsg, m.Client) } func (m *MessageApi) DeleteMsgs(c *gin.Context) { - a2r.CallV2(c, msg.DeleteMsgsCaller.Invoke) + a2r.Call(c, msg.MsgClient.DeleteMsgs, m.Client) } func (m *MessageApi) DeleteMsgPhysicalBySeq(c *gin.Context) { - a2r.CallV2(c, msg.DeleteMsgPhysicalBySeqCaller.Invoke) + a2r.Call(c, msg.MsgClient.DeleteMsgPhysicalBySeq, m.Client) } func (m *MessageApi) DeleteMsgPhysical(c *gin.Context) { - a2r.CallV2(c, msg.DeleteMsgPhysicalCaller.Invoke) + a2r.Call(c, msg.MsgClient.DeleteMsgPhysical, m.Client) } func (m *MessageApi) getSendMsgReq(c *gin.Context, req apistruct.SendMsg) (sendMsgReq *msg.SendMsgReq, err error) { @@ -170,14 +171,10 @@ func (m *MessageApi) getSendMsgReq(c *gin.Context, req apistruct.SendMsg) (sendM data = apistruct.AtElem{} case constant.Custom: data = apistruct.CustomElem{} - case constant.Quote: - data = apistruct.QuoteElem{} - case constant.Stream: - data = apistruct.StreamMsgElem{} case constant.OANotification: data = apistruct.OANotificationElem{} req.SessionType = constant.NotificationChatType - if err = user.GetNotificationAccountCaller.Execute(c, &user.GetNotificationAccountReq{UserID: req.SendID}); err != nil { + if err = m.userClient.GetNotificationByID(c, req.SendID); err != nil { return nil, err } default: @@ -224,7 +221,7 @@ func (m *MessageApi) SendMessage(c *gin.Context) { sendMsgReq.MsgData.RecvID = req.RecvID // Attempt to send the message using the client. - respPb, err := msg.SendMsgCaller.Invoke(c, sendMsgReq) + respPb, err := m.Client.SendMsg(c, sendMsgReq) if err != nil { // Set the status to failed and respond with an error if sending fails. apiresp.GinError(c, err) @@ -235,7 +232,7 @@ func (m *MessageApi) SendMessage(c *gin.Context) { var status = constant.MsgSendSuccessed // Attempt to update the message sending status in the system. - err = msg.SetSendMsgStatusCaller.Execute(c, &msg.SetSendMsgStatusReq{ + _, err = m.Client.SetSendMsgStatus(c, &msg.SetSendMsgStatusReq{ Status: int32(status), }) @@ -287,7 +284,7 @@ func (m *MessageApi) SendBusinessNotification(c *gin.Context) { }), }, } - respPb, err := msg.SendMsgCaller.Invoke(c, &sendMsgReq) + respPb, err := m.Client.SendMsg(c, &sendMsgReq) if err != nil { apiresp.GinError(c, err) return @@ -311,13 +308,10 @@ func (m *MessageApi) BatchSendMsg(c *gin.Context) { var recvIDs []string if req.IsSendAll { - pageNumber := 1 - showNumber := 500 + var pageNumber int32 = 1 + const showNumber = 500 for { - recvIDsPart, err := rpccall.ExtractField(c, user.GetAllUserIDCaller.Invoke, &user.GetAllUserIDReq{Pagination: &sdkws.RequestPagination{ - PageNumber: int32(pageNumber), - ShowNumber: int32(showNumber), - }}, (*user.GetAllUserIDResp).GetUserIDs) + recvIDsPart, err := m.userClient.GetAllUserIDs(c, pageNumber, showNumber) if err != nil { apiresp.GinError(c, err) return @@ -339,7 +333,7 @@ func (m *MessageApi) BatchSendMsg(c *gin.Context) { } for _, recvID := range recvIDs { sendMsgReq.MsgData.RecvID = recvID - rpcResp, err := msg.SendMsgCaller.Invoke(c, sendMsgReq) + rpcResp, err := m.Client.SendMsg(c, sendMsgReq) if err != nil { resp.FailedIDs = append(resp.FailedIDs, recvID) continue @@ -355,33 +349,33 @@ func (m *MessageApi) BatchSendMsg(c *gin.Context) { } func (m *MessageApi) CheckMsgIsSendSuccess(c *gin.Context) { - a2r.CallV2(c, msg.GetSendMsgStatusCaller.Invoke) + a2r.Call(c, msg.MsgClient.GetSendMsgStatus, m.Client) } func (m *MessageApi) GetUsersOnlineStatus(c *gin.Context) { - a2r.CallV2(c, msg.GetSendMsgStatusCaller.Invoke) + a2r.Call(c, msg.MsgClient.GetSendMsgStatus, m.Client) } func (m *MessageApi) GetActiveUser(c *gin.Context) { - a2r.CallV2(c, msg.GetActiveUserCaller.Invoke) + a2r.Call(c, msg.MsgClient.GetActiveUser, m.Client) } func (m *MessageApi) GetActiveGroup(c *gin.Context) { - a2r.CallV2(c, msg.GetActiveGroupCaller.Invoke) + a2r.Call(c, msg.MsgClient.GetActiveGroup, m.Client) } func (m *MessageApi) SearchMsg(c *gin.Context) { - a2r.CallV2(c, msg.SearchMessageCaller.Invoke) + a2r.Call(c, msg.MsgClient.SearchMessage, m.Client) } func (m *MessageApi) GetServerTime(c *gin.Context) { - a2r.CallV2(c, msg.GetServerTimeCaller.Invoke) + a2r.Call(c, msg.MsgClient.GetServerTime, m.Client) } func (m *MessageApi) GetStreamMsg(c *gin.Context) { - a2r.CallV2(c, msg.GetStreamMsgCaller.Invoke) + a2r.Call(c, msg.MsgClient.GetServerTime, m.Client) } func (m *MessageApi) AppendStreamMsg(c *gin.Context) { - a2r.CallV2(c, msg.AppendStreamMsgCaller.Invoke) + a2r.Call(c, msg.MsgClient.GetServerTime, m.Client) } diff --git a/internal/api/router.go b/internal/api/router.go index e524901bd8..fa3ac2c092 100644 --- a/internal/api/router.go +++ b/internal/api/router.go @@ -1,29 +1,36 @@ package api import ( + "context" "fmt" "net/http" "strings" - "github.com/openimsdk/open-im-server/v3/internal/api/jssdk" - pbAuth "github.com/openimsdk/protocol/auth" - clientv3 "go.etcd.io/etcd/client/v3" - "github.com/gin-contrib/gzip" - "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "github.com/go-playground/validator/v10" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" - + "github.com/openimsdk/open-im-server/v3/internal/api/jssdk" + "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" + pbAuth "github.com/openimsdk/protocol/auth" "github.com/openimsdk/protocol/constant" + "github.com/openimsdk/protocol/conversation" + "github.com/openimsdk/protocol/group" + "github.com/openimsdk/protocol/msg" + "github.com/openimsdk/protocol/relation" + "github.com/openimsdk/protocol/third" + "github.com/openimsdk/protocol/user" "github.com/openimsdk/tools/apiresp" "github.com/openimsdk/tools/discovery" + "github.com/openimsdk/tools/discovery/etcd" "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/mw" + clientv3 "go.etcd.io/etcd/client/v3" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) const ( @@ -48,15 +55,43 @@ func prommetricsGin() gin.HandlerFunc { } } -func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config, client *clientv3.Client) *gin.Engine { - disCov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), +func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegistry, cfg *Config) (*gin.Engine, error) { + client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin"))) + authConn, err := client.GetConn(ctx, cfg.Discovery.RpcService.Auth) + if err != nil { + return nil, err + } + userConn, err := client.GetConn(ctx, cfg.Discovery.RpcService.User) + if err != nil { + return nil, err + } + groupConn, err := client.GetConn(ctx, cfg.Discovery.RpcService.Group) + if err != nil { + return nil, err + } + friendConn, err := client.GetConn(ctx, cfg.Discovery.RpcService.Friend) + if err != nil { + return nil, err + } + conversationConn, err := client.GetConn(ctx, cfg.Discovery.RpcService.Conversation) + if err != nil { + return nil, err + } + thirdConn, err := client.GetConn(ctx, cfg.Discovery.RpcService.Third) + if err != nil { + return nil, err + } + msgConn, err := client.GetConn(ctx, cfg.Discovery.RpcService.Msg) + if err != nil { + return nil, err + } gin.SetMode(gin.ReleaseMode) r := gin.New() if v, ok := binding.Validator.Engine().(*validator.Validate); ok { _ = v.RegisterValidation("required_if", RequiredIf) } - switch config.API.Api.CompressionLevel { + switch cfg.API.Api.CompressionLevel { case NoCompression: case DefaultCompression: r.Use(gzip.Gzip(gzip.DefaultCompression)) @@ -65,13 +100,12 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config, client case BestSpeed: r.Use(gzip.Gzip(gzip.BestSpeed)) } - r.Use(prommetricsGin(), gin.RecoveryWithWriter(gin.DefaultErrorWriter, mw.GinPanicErr), mw.CorsHandler(), mw.GinParseOperationID(), GinParseToken()) - u := NewUserApi(disCov, config.Discovery.RpcService.MessageGateway) - m := NewMessageApi(config.Share.IMAdminUserID) + r.Use(prommetricsGin(), gin.RecoveryWithWriter(gin.DefaultErrorWriter, mw.GinPanicErr), mw.CorsHandler(), mw.GinParseOperationID(), GinParseToken(rpcli.NewAuthClient(authConn))) j := jssdk.NewJSSdkApi() - userRouterGroup := r.Group("/user") + u := NewUserApi(user.NewUserClient(userConn), client, cfg.Discovery.RpcService) { + userRouterGroup := r.Group("/user") userRouterGroup.POST("/user_register", u.UserRegister) userRouterGroup.POST("/update_user_info", u.UpdateUserInfo) userRouterGroup.POST("/update_user_info_ex", u.UpdateUserInfoEx) @@ -97,9 +131,9 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config, client userRouterGroup.POST("/search_notification_account", u.SearchNotificationAccount) } // friend routing group - friendRouterGroup := r.Group("/friend") { - f := NewFriendApi() + f := NewFriendApi(relation.NewFriendClient(friendConn)) + friendRouterGroup := r.Group("/friend") friendRouterGroup.POST("/delete_friend", f.DeleteFriend) friendRouterGroup.POST("/get_friend_apply_list", f.GetFriendApplyList) friendRouterGroup.POST("/get_designated_friend_apply", f.GetDesignatedFriendsApply) @@ -122,9 +156,10 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config, client friendRouterGroup.POST("/get_incremental_friends", f.GetIncrementalFriends) friendRouterGroup.POST("/get_full_friend_user_ids", f.GetFullFriendUserIDs) } - g := NewGroupApi() - groupRouterGroup := r.Group("/group") + + g := NewGroupApi(group.NewGroupClient(groupConn)) { + groupRouterGroup := r.Group("/group") groupRouterGroup.POST("/create_group", g.CreateGroup) groupRouterGroup.POST("/set_group_info", g.SetGroupInfo) groupRouterGroup.POST("/set_group_info_ex", g.SetGroupInfoEx) @@ -158,18 +193,19 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config, client groupRouterGroup.POST("/get_full_join_group_ids", g.GetFullJoinGroupIDs) } // certificate - authRouterGroup := r.Group("/auth") { - a := NewAuthApi() + a := NewAuthApi(pbAuth.NewAuthClient(authConn)) + authRouterGroup := r.Group("/auth") authRouterGroup.POST("/get_admin_token", a.GetAdminToken) authRouterGroup.POST("/get_user_token", a.GetUserToken) authRouterGroup.POST("/parse_token", a.ParseToken) authRouterGroup.POST("/force_logout", a.ForceLogout) + } // Third service - thirdGroup := r.Group("/third") { - t := NewThirdApi(config.API.Prometheus.GrafanaURL) + t := NewThirdApi(third.NewThirdClient(thirdConn), cfg.API.Prometheus.GrafanaURL) + thirdGroup := r.Group("/third") thirdGroup.GET("/prometheus", t.GetPrometheus) thirdGroup.POST("/fcm_update_token", t.FcmUpdateToken) thirdGroup.POST("/set_app_badge", t.SetAppBadge) @@ -192,8 +228,9 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config, client objectGroup.GET("/*name", t.ObjectRedirect) } // Message - msgGroup := r.Group("/msg") + m := NewMessageApi(msg.NewMsgClient(msgConn), rpcli.NewUserClient(userConn), cfg.Share.IMAdminUserID) { + msgGroup := r.Group("/msg") msgGroup.POST("/newest_seq", m.GetSeq) msgGroup.POST("/search_msg", m.SearchMsg) msgGroup.POST("/send_msg", m.SendMessage) @@ -218,9 +255,9 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config, client msgGroup.POST("/append_stream_msg", m.AppendStreamMsg) } // Conversation - conversationGroup := r.Group("/conversation") { - c := NewConversationApi() + c := NewConversationApi(conversation.NewConversationClient(conversationConn)) + conversationGroup := r.Group("/conversation") conversationGroup.POST("/get_sorted_conversation_list", c.GetSortedConversationList) conversationGroup.POST("/get_all_conversations", c.GetAllConversations) conversationGroup.POST("/get_conversation", c.GetConversation) @@ -234,42 +271,51 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config, client conversationGroup.POST("/get_pinned_conversation_ids", c.GetPinnedConversationIDs) } - statisticsGroup := r.Group("/statistics") { + statisticsGroup := r.Group("/statistics") statisticsGroup.POST("/user/register", u.UserRegisterCount) statisticsGroup.POST("/user/active", m.GetActiveUser) statisticsGroup.POST("/group/create", g.GroupCreateCount) statisticsGroup.POST("/group/active", m.GetActiveGroup) } - jssdk := r.Group("/jssdk") - jssdk.POST("/get_conversations", j.GetConversations) - jssdk.POST("/get_active_conversations", j.GetActiveConversations) - - pd := NewPrometheusDiscoveryApi(config, disCov) - proDiscoveryGroup := r.Group("/prometheus_discovery", pd.Enable) - proDiscoveryGroup.GET("/api", pd.Api) - proDiscoveryGroup.GET("/user", pd.User) - proDiscoveryGroup.GET("/group", pd.Group) - proDiscoveryGroup.GET("/msg", pd.Msg) - proDiscoveryGroup.GET("/friend", pd.Friend) - proDiscoveryGroup.GET("/conversation", pd.Conversation) - proDiscoveryGroup.GET("/third", pd.Third) - proDiscoveryGroup.GET("/auth", pd.Auth) - proDiscoveryGroup.GET("/push", pd.Push) - proDiscoveryGroup.GET("/msg_gateway", pd.MessageGateway) - proDiscoveryGroup.GET("/msg_transfer", pd.MessageTransfer) + { + jssdk := r.Group("/jssdk") + jssdk.POST("/get_conversations", j.GetConversations) + jssdk.POST("/get_active_conversations", j.GetActiveConversations) + } + { + pd := NewPrometheusDiscoveryApi(cfg, client) + proDiscoveryGroup := r.Group("/prometheus_discovery", pd.Enable) + proDiscoveryGroup.GET("/api", pd.Api) + proDiscoveryGroup.GET("/user", pd.User) + proDiscoveryGroup.GET("/group", pd.Group) + proDiscoveryGroup.GET("/msg", pd.Msg) + proDiscoveryGroup.GET("/friend", pd.Friend) + proDiscoveryGroup.GET("/conversation", pd.Conversation) + proDiscoveryGroup.GET("/third", pd.Third) + proDiscoveryGroup.GET("/auth", pd.Auth) + proDiscoveryGroup.GET("/push", pd.Push) + proDiscoveryGroup.GET("/msg_gateway", pd.MessageGateway) + proDiscoveryGroup.GET("/msg_transfer", pd.MessageTransfer) + } - cm := NewConfigManager(config.Share.IMAdminUserID, config.AllConfig, client, config.ConfigPath, config.RuntimeEnv) - configGroup := r.Group("/config", cm.CheckAdmin) - configGroup.POST("/get_config_list", cm.GetConfigList) - configGroup.POST("/get_config", cm.GetConfig) - configGroup.POST("/set_config", cm.SetConfig) - configGroup.POST("/reset_config", cm.ResetConfig) - return r + { + var etcdClient *clientv3.Client + if cfg.Discovery.Enable == config.ETCD { + etcdClient = client.(*etcd.SvcDiscoveryRegistryImpl).GetClient() + } + cm := NewConfigManager(cfg.Share.IMAdminUserID, cfg.AllConfig, etcdClient, cfg.ConfigPath, cfg.RuntimeEnv) + configGroup := r.Group("/config", cm.CheckAdmin) + configGroup.POST("/get_config_list", cm.GetConfigList) + configGroup.POST("/get_config", cm.GetConfig) + configGroup.POST("/set_config", cm.SetConfig) + configGroup.POST("/reset_config", cm.ResetConfig) + } + return r, nil } -func GinParseToken() gin.HandlerFunc { +func GinParseToken(authClient *rpcli.AuthClient) gin.HandlerFunc { return func(c *gin.Context) { switch c.Request.Method { case http.MethodPost: @@ -287,7 +333,7 @@ func GinParseToken() gin.HandlerFunc { c.Abort() return } - resp, err := pbAuth.ParseTokenCaller.Invoke(c, &pbAuth.ParseTokenReq{Token: token}) + resp, err := authClient.ParseToken(c, token) if err != nil { apiresp.GinError(c, err) c.Abort() diff --git a/internal/api/statistics.go b/internal/api/statistics.go deleted file mode 100644 index f60bddb2eb..0000000000 --- a/internal/api/statistics.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright © 2023 OpenIM. 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 api - -import ( - "github.com/gin-gonic/gin" - "github.com/openimsdk/protocol/user" - "github.com/openimsdk/tools/a2r" -) - -type StatisticsApi struct{} - -func NewStatisticsApi() StatisticsApi { - return StatisticsApi{} -} - -func (s *StatisticsApi) UserRegister(c *gin.Context) { - a2r.CallV2(c, user.UserRegisterCountCaller.Invoke) -} diff --git a/internal/api/third.go b/internal/api/third.go index ac02e37347..7ecb329112 100644 --- a/internal/api/third.go +++ b/internal/api/third.go @@ -16,14 +16,13 @@ package api import ( "context" + "google.golang.org/grpc" "math/rand" "net/http" "net/url" "strconv" "strings" - "google.golang.org/grpc" - "github.com/gin-gonic/gin" "github.com/openimsdk/protocol/third" "github.com/openimsdk/tools/a2r" @@ -33,18 +32,19 @@ import ( type ThirdApi struct { GrafanaUrl string + Client third.ThirdClient } -func NewThirdApi(grafanaUrl string) ThirdApi { - return ThirdApi{GrafanaUrl: grafanaUrl} +func NewThirdApi(client third.ThirdClient, grafanaUrl string) ThirdApi { + return ThirdApi{Client: client, GrafanaUrl: grafanaUrl} } func (o *ThirdApi) FcmUpdateToken(c *gin.Context) { - a2r.CallV2(c, third.FcmUpdateTokenCaller.Invoke) + a2r.Call(c, third.ThirdClient.FcmUpdateToken, o.Client) } func (o *ThirdApi) SetAppBadge(c *gin.Context) { - a2r.CallV2(c, third.SetAppBadgeCaller.Invoke) + a2r.Call(c, third.ThirdClient.SetAppBadge, o.Client) } // #################### s3 #################### @@ -79,44 +79,44 @@ func setURLPrefix(c *gin.Context, urlPrefix *string) error { } func (o *ThirdApi) PartLimit(c *gin.Context) { - a2r.CallV2(c, third.PartLimitCaller.Invoke) + a2r.Call(c, third.ThirdClient.PartLimit, o.Client) } func (o *ThirdApi) PartSize(c *gin.Context) { - a2r.CallV2(c, third.PartSizeCaller.Invoke) + a2r.Call(c, third.ThirdClient.PartSize, o.Client) } func (o *ThirdApi) InitiateMultipartUpload(c *gin.Context) { opt := setURLPrefixOption(third.ThirdClient.InitiateMultipartUpload, func(req *third.InitiateMultipartUploadReq) error { return setURLPrefix(c, &req.UrlPrefix) }) - a2r.CallV2(c, third.InitiateMultipartUploadCaller.Invoke, opt) + a2r.Call(c, third.ThirdClient.InitiateMultipartUpload, o.Client, opt) } func (o *ThirdApi) AuthSign(c *gin.Context) { - a2r.CallV2(c, third.AuthSignCaller.Invoke) + a2r.Call(c, third.ThirdClient.AuthSign, o.Client) } func (o *ThirdApi) CompleteMultipartUpload(c *gin.Context) { opt := setURLPrefixOption(third.ThirdClient.CompleteMultipartUpload, func(req *third.CompleteMultipartUploadReq) error { return setURLPrefix(c, &req.UrlPrefix) }) - a2r.CallV2(c, third.CompleteMultipartUploadCaller.Invoke, opt) + a2r.Call(c, third.ThirdClient.CompleteMultipartUpload, o.Client, opt) } func (o *ThirdApi) AccessURL(c *gin.Context) { - a2r.CallV2(c, third.AccessURLCaller.Invoke) + a2r.Call(c, third.ThirdClient.AccessURL, o.Client) } func (o *ThirdApi) InitiateFormData(c *gin.Context) { - a2r.CallV2(c, third.InitiateFormDataCaller.Invoke) + a2r.Call(c, third.ThirdClient.InitiateFormData, o.Client) } func (o *ThirdApi) CompleteFormData(c *gin.Context) { opt := setURLPrefixOption(third.ThirdClient.CompleteFormData, func(req *third.CompleteFormDataReq) error { return setURLPrefix(c, &req.UrlPrefix) }) - a2r.CallV2(c, third.CompleteFormDataCaller.Invoke, opt) + a2r.Call(c, third.ThirdClient.CompleteFormData, o.Client, opt) } func (o *ThirdApi) ObjectRedirect(c *gin.Context) { @@ -140,7 +140,7 @@ func (o *ThirdApi) ObjectRedirect(c *gin.Context) { } query[key] = values[0] } - resp, err := third.AccessURLCaller.Invoke(ctx, &third.AccessURLReq{Name: name, Query: query}) + resp, err := o.Client.AccessURL(ctx, &third.AccessURLReq{Name: name, Query: query}) if err != nil { if errs.ErrArgs.Is(err) { c.String(http.StatusBadRequest, err.Error()) @@ -158,15 +158,15 @@ func (o *ThirdApi) ObjectRedirect(c *gin.Context) { // #################### logs ####################. func (o *ThirdApi) UploadLogs(c *gin.Context) { - a2r.CallV2(c, third.UploadLogsCaller.Invoke) + a2r.Call(c, third.ThirdClient.UploadLogs, o.Client) } func (o *ThirdApi) DeleteLogs(c *gin.Context) { - a2r.CallV2(c, third.DeleteLogsCaller.Invoke) + a2r.Call(c, third.ThirdClient.DeleteLogs, o.Client) } func (o *ThirdApi) SearchLogs(c *gin.Context) { - a2r.CallV2(c, third.SearchLogsCaller.Invoke) + a2r.Call(c, third.ThirdClient.SearchLogs, o.Client) } func (o *ThirdApi) GetPrometheus(c *gin.Context) { diff --git a/internal/api/user.go b/internal/api/user.go index e1024e50b5..a88f8f65a5 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -16,6 +16,7 @@ package api import ( "github.com/gin-gonic/gin" + "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/msggateway" "github.com/openimsdk/protocol/user" @@ -27,47 +28,45 @@ import ( ) type UserApi struct { - Discov discovery.SvcDiscoveryRegistry - MessageGateWayRpcName string + Client user.UserClient + discov discovery.SvcDiscoveryRegistry + config config.RpcService } -func NewUserApi(discov discovery.SvcDiscoveryRegistry, messageGateWayRpcName string) UserApi { - return UserApi{ - Discov: discov, - MessageGateWayRpcName: messageGateWayRpcName, - } +func NewUserApi(client user.UserClient, discov discovery.SvcDiscoveryRegistry, config config.RpcService) UserApi { + return UserApi{Client: client, discov: discov, config: config} } func (u *UserApi) UserRegister(c *gin.Context) { - a2r.CallV2(c, user.UserRegisterCaller.Invoke) + a2r.Call(c, user.UserClient.UserRegister, u.Client) } // UpdateUserInfo is deprecated. Use UpdateUserInfoEx func (u *UserApi) UpdateUserInfo(c *gin.Context) { - a2r.CallV2(c, user.UpdateUserInfoCaller.Invoke) + a2r.Call(c, user.UserClient.UpdateUserInfo, u.Client) } func (u *UserApi) UpdateUserInfoEx(c *gin.Context) { - a2r.CallV2(c, user.UpdateUserInfoExCaller.Invoke) + a2r.Call(c, user.UserClient.UpdateUserInfoEx, u.Client) } func (u *UserApi) SetGlobalRecvMessageOpt(c *gin.Context) { - a2r.CallV2(c, user.SetGlobalRecvMessageOptCaller.Invoke) + a2r.Call(c, user.UserClient.SetGlobalRecvMessageOpt, u.Client) } func (u *UserApi) GetUsersPublicInfo(c *gin.Context) { - a2r.CallV2(c, user.GetDesignateUsersCaller.Invoke) + a2r.Call(c, user.UserClient.GetDesignateUsers, u.Client) } func (u *UserApi) GetAllUsersID(c *gin.Context) { - a2r.CallV2(c, user.GetAllUserIDCaller.Invoke) + a2r.Call(c, user.UserClient.GetAllUserID, u.Client) } func (u *UserApi) AccountCheck(c *gin.Context) { - a2r.CallV2(c, user.AccountCheckCaller.Invoke) + a2r.Call(c, user.UserClient.AccountCheck, u.Client) } func (u *UserApi) GetUsers(c *gin.Context) { - a2r.CallV2(c, user.GetPaginationUsersCaller.Invoke) + a2r.Call(c, user.UserClient.GetPaginationUsers, u.Client) } // GetUsersOnlineStatus Get user online status. @@ -77,7 +76,7 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { apiresp.GinError(c, err) return } - conns, err := u.Discov.GetConns(c, u.MessageGateWayRpcName) + conns, err := u.discov.GetConns(c, u.config.MessageGateway) if err != nil { apiresp.GinError(c, err) return @@ -128,7 +127,7 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { } func (u *UserApi) UserRegisterCount(c *gin.Context) { - a2r.CallV2(c, user.UserRegisterCountCaller.Invoke) + a2r.Call(c, user.UserClient.UserRegisterCount, u.Client) } // GetUsersOnlineTokenDetail Get user online token details. @@ -141,7 +140,7 @@ func (u *UserApi) GetUsersOnlineTokenDetail(c *gin.Context) { apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap()) return } - conns, err := u.Discov.GetConns(c, u.MessageGateWayRpcName) + conns, err := u.discov.GetConns(c, u.config.MessageGateway) if err != nil { apiresp.GinError(c, err) return @@ -194,52 +193,52 @@ func (u *UserApi) GetUsersOnlineTokenDetail(c *gin.Context) { // SubscriberStatus Presence status of subscribed users. func (u *UserApi) SubscriberStatus(c *gin.Context) { - a2r.CallV2(c, user.SubscribeOrCancelUsersStatusCaller.Invoke) + a2r.Call(c, user.UserClient.SubscribeOrCancelUsersStatus, u.Client) } // GetUserStatus Get the online status of the user. func (u *UserApi) GetUserStatus(c *gin.Context) { - a2r.CallV2(c, user.GetUserStatusCaller.Invoke) + a2r.Call(c, user.UserClient.GetUserStatus, u.Client) } // GetSubscribeUsersStatus Get the online status of subscribers. func (u *UserApi) GetSubscribeUsersStatus(c *gin.Context) { - a2r.CallV2(c, user.GetSubscribeUsersStatusCaller.Invoke) + a2r.Call(c, user.UserClient.GetSubscribeUsersStatus, u.Client) } // ProcessUserCommandAdd user general function add. func (u *UserApi) ProcessUserCommandAdd(c *gin.Context) { - a2r.CallV2(c, user.ProcessUserCommandAddCaller.Invoke) + a2r.Call(c, user.UserClient.ProcessUserCommandAdd, u.Client) } // ProcessUserCommandDelete user general function delete. func (u *UserApi) ProcessUserCommandDelete(c *gin.Context) { - a2r.CallV2(c, user.ProcessUserCommandDeleteCaller.Invoke) + a2r.Call(c, user.UserClient.ProcessUserCommandDelete, u.Client) } // ProcessUserCommandUpdate user general function update. func (u *UserApi) ProcessUserCommandUpdate(c *gin.Context) { - a2r.CallV2(c, user.ProcessUserCommandUpdateCaller.Invoke) + a2r.Call(c, user.UserClient.ProcessUserCommandUpdate, u.Client) } // ProcessUserCommandGet user general function get. func (u *UserApi) ProcessUserCommandGet(c *gin.Context) { - a2r.CallV2(c, user.ProcessUserCommandGetCaller.Invoke) + a2r.Call(c, user.UserClient.ProcessUserCommandGet, u.Client) } // ProcessUserCommandGet user general function get all. func (u *UserApi) ProcessUserCommandGetAll(c *gin.Context) { - a2r.CallV2(c, user.ProcessUserCommandGetAllCaller.Invoke) + a2r.Call(c, user.UserClient.ProcessUserCommandGetAll, u.Client) } func (u *UserApi) AddNotificationAccount(c *gin.Context) { - a2r.CallV2(c, user.AddNotificationAccountCaller.Invoke) + a2r.Call(c, user.UserClient.AddNotificationAccount, u.Client) } func (u *UserApi) UpdateNotificationAccountInfo(c *gin.Context) { - a2r.CallV2(c, user.UpdateNotificationAccountInfoCaller.Invoke) + a2r.Call(c, user.UserClient.UpdateNotificationAccountInfo, u.Client) } func (u *UserApi) SearchNotificationAccount(c *gin.Context) { - a2r.CallV2(c, user.SearchNotificationAccountCaller.Invoke) + a2r.Call(c, user.UserClient.SearchNotificationAccount, u.Client) } diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index 43386ed9a1..52afe495b6 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -16,6 +16,7 @@ package msggateway import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "sync/atomic" "github.com/openimsdk/open-im-server/v3/pkg/authverify" @@ -34,7 +35,14 @@ import ( ) func (s *Server) InitServer(ctx context.Context, config *Config, disCov discovery.SvcDiscoveryRegistry, server *grpc.Server) error { - s.LongConnServer.SetDiscoveryRegistry(disCov, config) + userConn, err := disCov.GetConn(ctx, config.Discovery.RpcService.User) + if err != nil { + return err + } + s.userClient = rpcli.NewUserClient(userConn) + if err := s.LongConnServer.SetDiscoveryRegistry(ctx, disCov, config); err != nil { + return err + } msggateway.RegisterMsgGatewayServer(server, s) if s.ready != nil { return s.ready(s) @@ -68,6 +76,7 @@ type Server struct { pushTerminal map[int]struct{} ready func(srv *Server) error queue *memamq.MemoryQueue + userClient *rpcli.UserClient } func (s *Server) SetLongConnServer(LongConnServer LongConnServer) { diff --git a/internal/msggateway/init.go b/internal/msggateway/init.go index 156d32b4d9..6614b96bdb 100644 --- a/internal/msggateway/init.go +++ b/internal/msggateway/init.go @@ -62,8 +62,9 @@ func Start(ctx context.Context, index int, conf *Config) error { ) hubServer := NewServer(longServer, conf, func(srv *Server) error { - longServer.online, _ = rpccache.NewOnlineCache(conf.Share.IMAdminUserID, nil, rdb, false, longServer.subscriberUserOnlineStatusChanges) - return nil + var err error + longServer.online, err = rpccache.NewOnlineCache(srv.userClient, nil, rdb, false, longServer.subscriberUserOnlineStatusChanges) + return err }) go longServer.ChangeOnlineStatus(4) diff --git a/internal/msggateway/message_handler.go b/internal/msggateway/message_handler.go index d88d2fbfd8..9b59867d61 100644 --- a/internal/msggateway/message_handler.go +++ b/internal/msggateway/message_handler.go @@ -17,6 +17,7 @@ package msggateway import ( "context" "encoding/json" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "sync" "github.com/go-playground/validator/v10" @@ -99,27 +100,33 @@ func (r *Resp) String() string { } type MessageHandler interface { - GetSeq(context context.Context, data *Req) ([]byte, error) - SendMessage(context context.Context, data *Req) ([]byte, error) - SendSignalMessage(context context.Context, data *Req) ([]byte, error) - PullMessageBySeqList(context context.Context, data *Req) ([]byte, error) - GetConversationsHasReadAndMaxSeq(context context.Context, data *Req) ([]byte, error) - GetSeqMessage(context context.Context, data *Req) ([]byte, error) - UserLogout(context context.Context, data *Req) ([]byte, error) - SetUserDeviceBackground(context context.Context, data *Req) ([]byte, bool, error) + GetSeq(ctx context.Context, data *Req) ([]byte, error) + SendMessage(ctx context.Context, data *Req) ([]byte, error) + SendSignalMessage(ctx context.Context, data *Req) ([]byte, error) + PullMessageBySeqList(ctx context.Context, data *Req) ([]byte, error) + GetConversationsHasReadAndMaxSeq(ctx context.Context, data *Req) ([]byte, error) + GetSeqMessage(ctx context.Context, data *Req) ([]byte, error) + UserLogout(ctx context.Context, data *Req) ([]byte, error) + SetUserDeviceBackground(ctx context.Context, data *Req) ([]byte, bool, error) } var _ MessageHandler = (*GrpcHandler)(nil) type GrpcHandler struct { - validate *validator.Validate + validate *validator.Validate + msgClient *rpcli.MsgClient + pushClient *rpcli.PushMsgServiceClient } -func NewGrpcHandler(validate *validator.Validate) *GrpcHandler { - return &GrpcHandler{validate: validate} +func NewGrpcHandler(validate *validator.Validate, msgClient *rpcli.MsgClient, pushClient *rpcli.PushMsgServiceClient) *GrpcHandler { + return &GrpcHandler{ + validate: validate, + msgClient: msgClient, + pushClient: pushClient, + } } -func (g GrpcHandler) GetSeq(ctx context.Context, data *Req) ([]byte, error) { +func (g *GrpcHandler) GetSeq(ctx context.Context, data *Req) ([]byte, error) { req := sdkws.GetMaxSeqReq{} if err := proto.Unmarshal(data.Data, &req); err != nil { return nil, errs.WrapMsg(err, "GetSeq: error unmarshaling request", "action", "unmarshal", "dataType", "GetMaxSeqReq") @@ -127,7 +134,7 @@ func (g GrpcHandler) GetSeq(ctx context.Context, data *Req) ([]byte, error) { if err := g.validate.Struct(&req); err != nil { return nil, errs.WrapMsg(err, "GetSeq: validation failed", "action", "validate", "dataType", "GetMaxSeqReq") } - resp, err := msg.GetMaxSeqCaller.Invoke(ctx, &req) + resp, err := g.msgClient.MsgClient.GetMaxSeq(ctx, &req) if err != nil { return nil, err } @@ -140,7 +147,7 @@ func (g GrpcHandler) GetSeq(ctx context.Context, data *Req) ([]byte, error) { // SendMessage handles the sending of messages through gRPC. It unmarshals the request data, // validates the message, and then sends it using the message RPC client. -func (g GrpcHandler) SendMessage(ctx context.Context, data *Req) ([]byte, error) { +func (g *GrpcHandler) SendMessage(ctx context.Context, data *Req) ([]byte, error) { var msgData sdkws.MsgData if err := proto.Unmarshal(data.Data, &msgData); err != nil { return nil, errs.WrapMsg(err, "SendMessage: error unmarshaling message data", "action", "unmarshal", "dataType", "MsgData") @@ -151,7 +158,7 @@ func (g GrpcHandler) SendMessage(ctx context.Context, data *Req) ([]byte, error) } req := msg.SendMsgReq{MsgData: &msgData} - resp, err := msg.SendMsgCaller.Invoke(ctx, &req) + resp, err := g.msgClient.MsgClient.SendMsg(ctx, &req) if err != nil { return nil, err } @@ -164,8 +171,8 @@ func (g GrpcHandler) SendMessage(ctx context.Context, data *Req) ([]byte, error) return c, nil } -func (g GrpcHandler) SendSignalMessage(context context.Context, data *Req) ([]byte, error) { - resp, err := msg.SendMsgCaller.Invoke(context, nil) +func (g *GrpcHandler) SendSignalMessage(ctx context.Context, data *Req) ([]byte, error) { + resp, err := g.msgClient.MsgClient.SendMsg(ctx, nil) if err != nil { return nil, err } @@ -176,7 +183,7 @@ func (g GrpcHandler) SendSignalMessage(context context.Context, data *Req) ([]by return c, nil } -func (g GrpcHandler) PullMessageBySeqList(ctx context.Context, data *Req) ([]byte, error) { +func (g *GrpcHandler) PullMessageBySeqList(ctx context.Context, data *Req) ([]byte, error) { req := sdkws.PullMessageBySeqsReq{} if err := proto.Unmarshal(data.Data, &req); err != nil { return nil, errs.WrapMsg(err, "err proto unmarshal", "action", "unmarshal", "dataType", "PullMessageBySeqsReq") @@ -184,7 +191,7 @@ func (g GrpcHandler) PullMessageBySeqList(ctx context.Context, data *Req) ([]byt if err := g.validate.Struct(data); err != nil { return nil, errs.WrapMsg(err, "validation failed", "action", "validate", "dataType", "PullMessageBySeqsReq") } - resp, err := msg.PullMessageBySeqsCaller.Invoke(ctx, &req) + resp, err := g.msgClient.MsgClient.PullMessageBySeqs(ctx, &req) if err != nil { return nil, err } @@ -195,7 +202,7 @@ func (g GrpcHandler) PullMessageBySeqList(ctx context.Context, data *Req) ([]byt return c, nil } -func (g GrpcHandler) GetConversationsHasReadAndMaxSeq(ctx context.Context, data *Req) ([]byte, error) { +func (g *GrpcHandler) GetConversationsHasReadAndMaxSeq(ctx context.Context, data *Req) ([]byte, error) { req := msg.GetConversationsHasReadAndMaxSeqReq{} if err := proto.Unmarshal(data.Data, &req); err != nil { return nil, errs.WrapMsg(err, "err proto unmarshal", "action", "unmarshal", "dataType", "GetConversationsHasReadAndMaxSeq") @@ -203,7 +210,7 @@ func (g GrpcHandler) GetConversationsHasReadAndMaxSeq(ctx context.Context, data if err := g.validate.Struct(data); err != nil { return nil, errs.WrapMsg(err, "validation failed", "action", "validate", "dataType", "GetConversationsHasReadAndMaxSeq") } - resp, err := msg.GetConversationsHasReadAndMaxSeqCaller.Invoke(ctx, &req) + resp, err := g.msgClient.MsgClient.GetConversationsHasReadAndMaxSeq(ctx, &req) if err != nil { return nil, err } @@ -214,7 +221,7 @@ func (g GrpcHandler) GetConversationsHasReadAndMaxSeq(ctx context.Context, data return c, nil } -func (g GrpcHandler) GetSeqMessage(ctx context.Context, data *Req) ([]byte, error) { +func (g *GrpcHandler) GetSeqMessage(ctx context.Context, data *Req) ([]byte, error) { req := msg.GetSeqMessageReq{} if err := proto.Unmarshal(data.Data, &req); err != nil { return nil, errs.WrapMsg(err, "error unmarshaling request", "action", "unmarshal", "dataType", "GetSeqMessage") @@ -222,7 +229,7 @@ func (g GrpcHandler) GetSeqMessage(ctx context.Context, data *Req) ([]byte, erro if err := g.validate.Struct(data); err != nil { return nil, errs.WrapMsg(err, "validation failed", "action", "validate", "dataType", "GetSeqMessage") } - resp, err := msg.GetSeqMessageCaller.Invoke(ctx, &req) + resp, err := g.msgClient.MsgClient.GetSeqMessage(ctx, &req) if err != nil { return nil, err } @@ -233,12 +240,12 @@ func (g GrpcHandler) GetSeqMessage(ctx context.Context, data *Req) ([]byte, erro return c, nil } -func (g GrpcHandler) UserLogout(ctx context.Context, data *Req) ([]byte, error) { +func (g *GrpcHandler) UserLogout(ctx context.Context, data *Req) ([]byte, error) { req := push.DelUserPushTokenReq{} if err := proto.Unmarshal(data.Data, &req); err != nil { return nil, errs.WrapMsg(err, "error unmarshaling request", "action", "unmarshal", "dataType", "DelUserPushTokenReq") } - resp, err := push.DelUserPushTokenCaller.Invoke(ctx, &req) + resp, err := g.pushClient.PushMsgServiceClient.DelUserPushToken(ctx, &req) if err != nil { return nil, err } @@ -249,7 +256,7 @@ func (g GrpcHandler) UserLogout(ctx context.Context, data *Req) ([]byte, error) return c, nil } -func (g GrpcHandler) SetUserDeviceBackground(_ context.Context, data *Req) ([]byte, bool, error) { +func (g *GrpcHandler) SetUserDeviceBackground(ctx context.Context, data *Req) ([]byte, bool, error) { req := sdkws.SetAppBackgroundStatusReq{} if err := proto.Unmarshal(data.Data, &req); err != nil { return nil, false, errs.WrapMsg(err, "error unmarshaling request", "action", "unmarshal", "dataType", "SetAppBackgroundStatusReq") diff --git a/internal/msggateway/online.go b/internal/msggateway/online.go index bff2639976..52b6c5d05f 100644 --- a/internal/msggateway/online.go +++ b/internal/msggateway/online.go @@ -88,7 +88,7 @@ func (ws *WsServer) ChangeOnlineStatus(concurrent int) { opIdCtx := mcontext.SetOperationID(context.Background(), operationIDPrefix+strconv.FormatInt(count.Add(1), 10)) ctx, cancel := context.WithTimeout(opIdCtx, time.Second*5) defer cancel() - if err := pbuser.SetUserOnlineStatusCaller.Execute(ctx, req); err != nil { + if err := ws.userClient.SetUserOnlineStatus(ctx, req); err != nil { log.ZError(ctx, "update user online status", err) } for _, ss := range req.Status { diff --git a/internal/msggateway/ws_server.go b/internal/msggateway/ws_server.go index 095d1adbce..fe2c1398f7 100644 --- a/internal/msggateway/ws_server.go +++ b/internal/msggateway/ws_server.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "net/http" "sync" "sync/atomic" @@ -33,7 +34,7 @@ type LongConnServer interface { GetUserAllCons(userID string) ([]*Client, bool) GetUserPlatformCons(userID string, platform int) ([]*Client, bool, bool) Validate(s any) error - SetDiscoveryRegistry(client discovery.SvcDiscoveryRegistry, config *Config) + SetDiscoveryRegistry(ctx context.Context, client discovery.SvcDiscoveryRegistry, config *Config) error KickUserConn(client *Client) error UnRegister(c *Client) SetKickHandlerInfo(i *kickHandler) @@ -63,6 +64,8 @@ type WsServer struct { //Encoder MessageHandler webhookClient *webhook.Client + userClient *rpcli.UserClient + authClient *rpcli.AuthClient } type kickHandler struct { @@ -71,9 +74,28 @@ type kickHandler struct { newClient *Client } -func (ws *WsServer) SetDiscoveryRegistry(disCov discovery.SvcDiscoveryRegistry, config *Config) { - ws.MessageHandler = NewGrpcHandler(ws.validate) +func (ws *WsServer) SetDiscoveryRegistry(ctx context.Context, disCov discovery.SvcDiscoveryRegistry, config *Config) error { + userConn, err := disCov.GetConn(ctx, config.Discovery.RpcService.User) + if err != nil { + return err + } + pushConn, err := disCov.GetConn(ctx, config.Discovery.RpcService.Push) + if err != nil { + return err + } + authConn, err := disCov.GetConn(ctx, config.Discovery.RpcService.Auth) + if err != nil { + return err + } + msgConn, err := disCov.GetConn(ctx, config.Discovery.RpcService.Msg) + if err != nil { + return err + } + ws.userClient = rpcli.NewUserClient(userConn) + ws.authClient = rpcli.NewAuthClient(authConn) + ws.MessageHandler = NewGrpcHandler(ws.validate, rpcli.NewMsgClient(msgConn), rpcli.NewPushMsgServiceClient(pushConn)) ws.disCov = disCov + return nil } //func (ws *WsServer) SetUserOnlineStatus(ctx context.Context, client *Client, status int32) { @@ -315,8 +337,7 @@ func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Clien []string{newClient.ctx.GetOperationID(), newClient.ctx.GetUserID(), constant.PlatformIDToName(newClient.PlatformID), newClient.ctx.GetConnID()}, ) - - if err := pbAuth.KickTokensCaller.Execute(ctx, &pbAuth.KickTokensReq{Tokens: kickTokens}); err != nil { + if err := ws.authClient.KickTokens(ctx, kickTokens); err != nil { log.ZWarn(newClient.ctx, "kickTokens err", err) } } @@ -343,11 +364,12 @@ func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Clien []string{newClient.ctx.GetOperationID(), newClient.ctx.GetUserID(), constant.PlatformIDToName(newClient.PlatformID), newClient.ctx.GetConnID()}, ) - if err := pbAuth.InvalidateTokenCaller.Execute(ctx, &pbAuth.InvalidateTokenReq{ + req := &pbAuth.InvalidateTokenReq{ PreservedToken: newClient.token, UserID: newClient.UserID, PlatformID: int32(newClient.PlatformID), - }); err != nil { + } + if err := ws.authClient.InvalidateToken(ctx, req); err != nil { log.ZWarn(newClient.ctx, "InvalidateToken err", err, "userID", newClient.UserID, "platformID", newClient.PlatformID) } @@ -418,7 +440,7 @@ func (ws *WsServer) wsHandler(w http.ResponseWriter, r *http.Request) { } // Call the authentication client to parse the Token obtained from the context - resp, err := pbAuth.ParseTokenCaller.Invoke(connContext, &pbAuth.ParseTokenReq{Token: connContext.GetToken()}) + resp, err := ws.authClient.ParseToken(connContext, connContext.GetToken()) if err != nil { // If there's an error parsing the Token, decide whether to send the error message via WebSocket based on the context flag shouldSendError := connContext.ShouldSendResp() diff --git a/internal/msgtransfer/init.go b/internal/msgtransfer/init.go index bf02f6a7bf..c519a7e2a4 100644 --- a/internal/msgtransfer/init.go +++ b/internal/msgtransfer/init.go @@ -26,7 +26,6 @@ import ( "syscall" disetcd "github.com/openimsdk/open-im-server/v3/pkg/common/discovery/etcd" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/tools/discovery" "github.com/openimsdk/tools/discovery/etcd" "github.com/openimsdk/tools/utils/jsonutil" @@ -94,9 +93,6 @@ func Start(ctx context.Context, index int, config *Config) error { } client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin"))) - if err = rpcclient.InitRpcCaller(client, config.Discovery.RpcService); err != nil { - return err - } if config.Discovery.Enable == conf.ETCD { cm := disetcd.NewConfigManager(client.(*etcd.SvcDiscoveryRegistryImpl).GetClient(), []string{ @@ -130,7 +126,7 @@ func Start(ctx context.Context, index int, config *Config) error { if err != nil { return err } - historyCH, err := NewOnlineHistoryRedisConsumerHandler(&config.KafkaConfig, msgTransferDatabase) + historyCH, err := NewOnlineHistoryRedisConsumerHandler(ctx, client, config, msgTransferDatabase) if err != nil { return err } diff --git a/internal/msgtransfer/online_history_msg_handler.go b/internal/msgtransfer/online_history_msg_handler.go index 9287d6b617..83b0750613 100644 --- a/internal/msgtransfer/online_history_msg_handler.go +++ b/internal/msgtransfer/online_history_msg_handler.go @@ -18,6 +18,8 @@ import ( "context" "encoding/json" "errors" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" + "github.com/openimsdk/tools/discovery" "strconv" "strings" "sync" @@ -25,15 +27,12 @@ import ( "github.com/IBM/sarama" "github.com/go-redis/redis" - "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" "github.com/openimsdk/open-im-server/v3/pkg/tools/batcher" "github.com/openimsdk/protocol/constant" pbconv "github.com/openimsdk/protocol/conversation" - "github.com/openimsdk/protocol/group" - "github.com/openimsdk/protocol/rpccall" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" @@ -72,16 +71,30 @@ type OnlineHistoryRedisConsumerHandler struct { msgTransferDatabase controller.MsgTransferDatabase conversationUserHasReadChan chan *userHasReadSeq wg sync.WaitGroup + + groupClient *rpcli.GroupClient + conversationClient *rpcli.ConversationClient } -func NewOnlineHistoryRedisConsumerHandler(kafkaConf *config.Kafka, database controller.MsgTransferDatabase) (*OnlineHistoryRedisConsumerHandler, error) { +func NewOnlineHistoryRedisConsumerHandler(ctx context.Context, client discovery.SvcDiscoveryRegistry, config *Config, database controller.MsgTransferDatabase) (*OnlineHistoryRedisConsumerHandler, error) { + kafkaConf := config.KafkaConfig historyConsumerGroup, err := kafka.NewMConsumerGroup(kafkaConf.Build(), kafkaConf.ToRedisGroupID, []string{kafkaConf.ToRedisTopic}, false) if err != nil { return nil, err } + groupConn, err := client.GetConn(ctx, config.Discovery.RpcService.Group) + if err != nil { + return nil, err + } + conversationConn, err := client.GetConn(ctx, config.Discovery.RpcService.Conversation) + if err != nil { + return nil, err + } var och OnlineHistoryRedisConsumerHandler och.msgTransferDatabase = database och.conversationUserHasReadChan = make(chan *userHasReadSeq, hasReadChanBuffer) + och.groupClient = rpcli.NewGroupClient(groupConn) + och.conversationClient = rpcli.NewConversationClient(conversationConn) och.wg.Add(1) b := batcher.New[sarama.ConsumerMessage]( @@ -109,15 +122,13 @@ func (och *OnlineHistoryRedisConsumerHandler) do(ctx context.Context, channelID ctx = mcontext.WithTriggerIDContext(ctx, val.TriggerID()) ctxMessages := och.parseConsumerMessages(ctx, val.Val()) ctx = withAggregationCtx(ctx, ctxMessages) - log.ZInfo(ctx, "msg arrived channel", "channel id", channelID, "msgList length", len(ctxMessages), - "key", val.Key()) + log.ZInfo(ctx, "msg arrived channel", "channel id", channelID, "msgList length", len(ctxMessages), "key", val.Key()) och.doSetReadSeq(ctx, ctxMessages) storageMsgList, notStorageMsgList, storageNotificationList, notStorageNotificationList := och.categorizeMessageLists(ctxMessages) log.ZDebug(ctx, "number of categorized messages", "storageMsgList", len(storageMsgList), "notStorageMsgList", - len(notStorageMsgList), "storageNotificationList", len(storageNotificationList), "notStorageNotificationList", - len(notStorageNotificationList)) + len(notStorageMsgList), "storageNotificationList", len(storageNotificationList), "notStorageNotificationList", len(notStorageNotificationList)) conversationIDMsg := msgprocessor.GetChatConversationIDByMsg(ctxMessages[0].message) conversationIDNotification := msgprocessor.GetNotificationConversationIDByMsg(ctxMessages[0].message) @@ -282,31 +293,26 @@ func (och *OnlineHistoryRedisConsumerHandler) handleMsg(ctx context.Context, key log.ZDebug(ctx, "group chat first create conversation", "conversationID", conversationID) - userIDs, err := rpccall.ExtractField(ctx, group.GetGroupMemberUserIDsCaller.Invoke, - &group.GetGroupMemberUserIDsReq{ - GroupID: msg.GroupID, - }, (*group.GetGroupMemberUserIDsResp).GetUserIDs) + userIDs, err := och.groupClient.GetGroupMemberUserIDs(ctx, msg.GroupID) if err != nil { log.ZWarn(ctx, "get group member ids error", err, "conversationID", conversationID) } else { log.ZInfo(ctx, "GetGroupMemberIDs end") - if err := pbconv.CreateGroupChatConversationsCaller.Execute(ctx, &pbconv.CreateGroupChatConversationsReq{ - UserIDs: userIDs, - GroupID: msg.GroupID, - }); err != nil { + if err := och.conversationClient.CreateGroupChatConversations(ctx, msg.GroupID, userIDs); err != nil { log.ZWarn(ctx, "single chat first create conversation error", err, "conversationID", conversationID) } } case constant.SingleChatType, constant.NotificationChatType: - if err := pbconv.CreateSingleChatConversationsCaller.Execute(ctx, &pbconv.CreateSingleChatConversationsReq{ + req := &pbconv.CreateSingleChatConversationsReq{ RecvID: msg.RecvID, SendID: msg.SendID, ConversationID: conversationID, ConversationType: msg.SessionType, - }); err != nil { + } + if err := och.conversationClient.CreateSingleChatConversations(ctx, req); err != nil { log.ZWarn(ctx, "single chat or notification first create conversation error", err, "conversationID", conversationID, "sessionType", msg.SessionType) } diff --git a/internal/push/push.go b/internal/push/push.go index 3247426e98..b7c1ec4272 100644 --- a/internal/push/push.go +++ b/internal/push/push.go @@ -37,11 +37,6 @@ type Config struct { runTimeEnv string } -func (p pushServer) PushMsg(ctx context.Context, req *pbpush.PushMsgReq) (*pbpush.PushMsgResp, error) { - //todo reserved Interface - return nil, nil -} - func (p pushServer) DelUserPushToken(ctx context.Context, req *pbpush.DelUserPushTokenReq) (resp *pbpush.DelUserPushTokenResp, err error) { if err = p.database.DelFcmToken(ctx, req.UserID, int(req.PlatformID)); err != nil { @@ -65,7 +60,7 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg database := controller.NewPushDatabase(cacheModel, &config.KafkaConfig) - consumer, err := NewConsumerHandler(config, database, offlinePusher, rdb, client) + consumer, err := NewConsumerHandler(ctx, config, database, offlinePusher, rdb, client) if err != nil { return err } diff --git a/internal/push/push_handler.go b/internal/push/push_handler.go index ee855e1223..d5d457c0d6 100644 --- a/internal/push/push_handler.go +++ b/internal/push/push_handler.go @@ -3,6 +3,7 @@ package push import ( "context" "encoding/json" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "math/rand" "strconv" "time" @@ -17,12 +18,8 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/rpccache" "github.com/openimsdk/open-im-server/v3/pkg/util/conversationutil" "github.com/openimsdk/protocol/constant" - pbconv "github.com/openimsdk/protocol/conversation" - "github.com/openimsdk/protocol/group" - "github.com/openimsdk/protocol/msg" "github.com/openimsdk/protocol/msggateway" pbpush "github.com/openimsdk/protocol/push" - "github.com/openimsdk/protocol/rpccall" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/discovery" "github.com/openimsdk/tools/log" @@ -45,9 +42,13 @@ type ConsumerHandler struct { conversationLocalCache *rpccache.ConversationLocalCache webhookClient *webhook.Client config *Config + userClient *rpcli.UserClient + groupClient *rpcli.GroupClient + msgClient *rpcli.MsgClient + conversationClient *rpcli.ConversationClient } -func NewConsumerHandler(config *Config, database controller.PushDatabase, offlinePusher offlinepush.OfflinePusher, rdb redis.UniversalClient, +func NewConsumerHandler(ctx context.Context, config *Config, database controller.PushDatabase, offlinePusher offlinepush.OfflinePusher, rdb redis.UniversalClient, client discovery.SvcDiscoveryRegistry) (*ConsumerHandler, error) { var consumerHandler ConsumerHandler var err error @@ -56,15 +57,35 @@ func NewConsumerHandler(config *Config, database controller.PushDatabase, offlin if err != nil { return nil, err } + userConn, err := client.GetConn(ctx, config.Discovery.RpcService.User) + if err != nil { + return nil, err + } + groupConn, err := client.GetConn(ctx, config.Discovery.RpcService.Group) + if err != nil { + return nil, err + } + msgConn, err := client.GetConn(ctx, config.Discovery.RpcService.Msg) + if err != nil { + return nil, err + } + conversationConn, err := client.GetConn(ctx, config.Discovery.RpcService.Conversation) + if err != nil { + return nil, err + } + consumerHandler.userClient = rpcli.NewUserClient(userConn) + consumerHandler.groupClient = rpcli.NewGroupClient(groupConn) + consumerHandler.msgClient = rpcli.NewMsgClient(msgConn) + consumerHandler.conversationClient = rpcli.NewConversationClient(conversationConn) consumerHandler.offlinePusher = offlinePusher consumerHandler.onlinePusher = NewOnlinePusher(client, config) - consumerHandler.groupLocalCache = rpccache.NewGroupLocalCache(&config.LocalCacheConfig, rdb) - consumerHandler.conversationLocalCache = rpccache.NewConversationLocalCache(&config.LocalCacheConfig, rdb) + consumerHandler.groupLocalCache = rpccache.NewGroupLocalCache(consumerHandler.groupClient, &config.LocalCacheConfig, rdb) + consumerHandler.conversationLocalCache = rpccache.NewConversationLocalCache(consumerHandler.conversationClient, &config.LocalCacheConfig, rdb) consumerHandler.webhookClient = webhook.NewWebhookClient(config.WebhooksConfig.URL) consumerHandler.config = config consumerHandler.pushDatabase = database - consumerHandler.onlineCache, err = rpccache.NewOnlineCache(config.Share.IMAdminUserID, consumerHandler.groupLocalCache, rdb, config.RpcConfig.FullUserCache, nil) + consumerHandler.onlineCache, err = rpccache.NewOnlineCache(consumerHandler.userClient, consumerHandler.groupLocalCache, rdb, config.RpcConfig.FullUserCache, nil) if err != nil { return nil, err } @@ -321,7 +342,7 @@ func (c *ConsumerHandler) groupMessagesHandler(ctx context.Context, groupID stri ctx = mcontext.WithOpUserIDContext(ctx, c.config.Share.IMAdminUserID[0]) } defer func(groupID string) { - if err = group.DismissGroupCaller.Execute(ctx, &group.DismissGroupReq{GroupID: groupID}); err != nil { + if err := c.groupClient.DismissGroup(ctx, groupID, true); err != nil { log.ZError(ctx, "DismissGroup Notification clear members", err, "groupID", groupID) } }(groupID) @@ -347,12 +368,7 @@ func (c *ConsumerHandler) offlinePushMsg(ctx context.Context, msg *sdkws.MsgData func (c *ConsumerHandler) filterGroupMessageOfflinePush(ctx context.Context, groupID string, msg *sdkws.MsgData, offlinePushUserIDs []string) (userIDs []string, err error) { - - //todo local cache Obtain the difference set through local comparison. - needOfflinePushUserIDs, err := rpccall.ExtractField(ctx, pbconv.GetConversationOfflinePushUserIDsCaller.Invoke, &pbconv.GetConversationOfflinePushUserIDsReq{ - ConversationID: conversationutil.GenGroupConversationID(groupID), - UserIDs: offlinePushUserIDs, - }, (*pbconv.GetConversationOfflinePushUserIDsResp).GetUserIDs) + needOfflinePushUserIDs, err := c.conversationClient.GetConversationOfflinePushUserIDs(ctx, conversationutil.GenGroupConversationID(groupID), offlinePushUserIDs) if err != nil { return nil, err } @@ -406,18 +422,11 @@ func (c *ConsumerHandler) getOfflinePushInfos(msg *sdkws.MsgData) (title, conten func (c *ConsumerHandler) DeleteMemberAndSetConversationSeq(ctx context.Context, groupID string, userIDs []string) error { conversationID := msgprocessor.GetConversationIDBySessionType(constant.ReadGroupChatType, groupID) - maxSeq, err := rpccall.ExtractField(ctx, msg.GetConversationMaxSeqCaller.Invoke, - &msg.GetConversationMaxSeqReq{ConversationID: conversationID}, - (*msg.GetConversationMaxSeqResp).GetMaxSeq) + maxSeq, err := c.msgClient.GetConversationMaxSeq(ctx, conversationID) if err != nil { return err } - - return pbconv.SetConversationMaxSeqCaller.Execute(ctx, &pbconv.SetConversationMaxSeqReq{ - ConversationID: conversationID, - OwnerUserID: userIDs, - MaxSeq: maxSeq, - }) + return c.conversationClient.SetConversationMaxSeq(ctx, conversationID, userIDs, maxSeq) } func unmarshalNotificationElem(bytes []byte, t any) error { @@ -425,6 +434,5 @@ func unmarshalNotificationElem(bytes []byte, t any) error { if err := json.Unmarshal(bytes, ¬ification); err != nil { return err } - return json.Unmarshal([]byte(notification.Detail), t) } diff --git a/internal/rpc/auth/auth.go b/internal/rpc/auth/auth.go index c220863c62..a2b14f40d8 100644 --- a/internal/rpc/auth/auth.go +++ b/internal/rpc/auth/auth.go @@ -17,6 +17,7 @@ package auth import ( "context" "errors" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "github.com/openimsdk/open-im-server/v3/pkg/common/config" redis2 "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis" @@ -28,7 +29,6 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" pbauth "github.com/openimsdk/protocol/auth" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/msggateway" @@ -44,6 +44,7 @@ type authServer struct { authDatabase controller.AuthDatabase RegisterCenter discovery.SvcDiscoveryRegistry config *Config + userClient *rpcli.UserClient } type Config struct { @@ -58,6 +59,10 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg if err != nil { return err } + userConn, err := client.GetConn(ctx, config.Discovery.RpcService.User) + if err != nil { + return err + } pbauth.RegisterAuthServer(server, &authServer{ RegisterCenter: client, authDatabase: controller.NewAuthDatabase( @@ -67,7 +72,8 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg config.Share.MultiLogin, config.Share.IMAdminUserID, ), - config: config, + config: config, + userClient: rpcli.NewUserClient(userConn), }) return nil } @@ -83,7 +89,7 @@ func (s *authServer) GetAdminToken(ctx context.Context, req *pbauth.GetAdminToke } - if _, err := rpcclient.GetUserInfo(ctx, req.UserID); err != nil { + if err := s.userClient.CheckUser(ctx, []string{req.UserID}); err != nil { return nil, err } @@ -112,7 +118,7 @@ func (s *authServer) GetUserToken(ctx context.Context, req *pbauth.GetUserTokenR if authverify.IsManagerUserID(req.UserID, s.config.Share.IMAdminUserID) { return nil, errs.ErrNoPermission.WrapMsg("don't get Admin token") } - if _, err := rpcclient.GetUserInfo(ctx, req.UserID); err != nil { + if err := s.userClient.CheckUser(ctx, []string{req.UserID}); err != nil { return nil, err } token, err := s.authDatabase.CreateToken(ctx, req.UserID, int(req.PlatformID)) @@ -153,10 +159,7 @@ func (s *authServer) parseToken(ctx context.Context, tokensString string) (claim return nil, servererrs.ErrTokenNotExist.Wrap() } -func (s *authServer) ParseToken( - ctx context.Context, - req *pbauth.ParseTokenReq, -) (resp *pbauth.ParseTokenResp, err error) { +func (s *authServer) ParseToken(ctx context.Context, req *pbauth.ParseTokenReq) (resp *pbauth.ParseTokenResp, err error) { resp = &pbauth.ParseTokenResp{} claims, err := s.parseToken(ctx, req.Token) if err != nil { diff --git a/internal/rpc/conversation/conversation.go b/internal/rpc/conversation/conversation.go index f534ca6dea..53364ff866 100644 --- a/internal/rpc/conversation/conversation.go +++ b/internal/rpc/conversation/conversation.go @@ -16,6 +16,7 @@ package conversation import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "sort" "time" @@ -26,15 +27,11 @@ import ( dbModel "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/open-im-server/v3/pkg/localcache" "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" - pbgroup "github.com/openimsdk/protocol/group" - pbmsg "github.com/openimsdk/protocol/msg" - "github.com/openimsdk/protocol/rpccall" "github.com/openimsdk/tools/db/redisutil" "github.com/openimsdk/open-im-server/v3/pkg/common/convert" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/protocol/constant" pbconversation "github.com/openimsdk/protocol/conversation" "github.com/openimsdk/protocol/sdkws" @@ -52,6 +49,10 @@ type conversationServer struct { conversationNotificationSender *ConversationNotificationSender config *Config + + userClient *rpcli.UserClient + msgClient *rpcli.MsgClient + groupClient *rpcli.GroupClient } type Config struct { @@ -77,11 +78,27 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg if err != nil { return err } + userConn, err := client.GetConn(ctx, config.Discovery.RpcService.User) + if err != nil { + return err + } + groupConn, err := client.GetConn(ctx, config.Discovery.RpcService.Group) + if err != nil { + return err + } + msgConn, err := client.GetConn(ctx, config.Discovery.RpcService.Msg) + if err != nil { + return err + } + msgClient := rpcli.NewMsgClient(msgConn) localcache.InitLocalCache(&config.LocalCacheConfig) pbconversation.RegisterConversationServer(server, &conversationServer{ - conversationNotificationSender: NewConversationNotificationSender(&config.NotificationConfig), + conversationNotificationSender: NewConversationNotificationSender(&config.NotificationConfig, msgClient), conversationDatabase: controller.NewConversationDatabase(conversationDB, redis.NewConversationRedis(rdb, &config.LocalCacheConfig, redis.GetRocksCacheOptions(), conversationDB), mgocli.GetTx()), + userClient: rpcli.NewUserClient(userConn), + groupClient: rpcli.NewGroupClient(groupConn), + msgClient: msgClient, }) return nil } @@ -118,19 +135,12 @@ func (c *conversationServer) GetSortedConversationList(ctx context.Context, req if len(conversations) == 0 { return nil, errs.ErrRecordNotFound.Wrap() } - - maxSeqs, err := rpccall.ExtractField(ctx, pbmsg.GetMaxSeqsCaller.Invoke, - &pbmsg.GetMaxSeqsReq{ConversationIDs: conversationIDs}, - (*pbmsg.SeqsInfoResp).GetMaxSeqs) + maxSeqs, err := c.msgClient.GetMaxSeqs(ctx, conversationIDs) if err != nil { return nil, err } - chatLogs, err := rpccall.ExtractField(ctx, pbmsg.GetMsgByConversationIDsCaller.Invoke, - &pbmsg.GetMsgByConversationIDsReq{ - ConversationIDs: conversationIDs, - MaxSeqs: maxSeqs, - }, (*pbmsg.GetMsgByConversationIDsResp).GetMsgDatas) + chatLogs, err := c.msgClient.GetMsgByConversationIDs(ctx, conversationIDs, maxSeqs) if err != nil { return nil, err } @@ -140,9 +150,7 @@ func (c *conversationServer) GetSortedConversationList(ctx context.Context, req return nil, err } - hasReadSeqs, err := rpccall.ExtractField(ctx, pbmsg.GetHasReadSeqsCaller.Invoke, - &pbmsg.GetHasReadSeqsReq{ConversationIDs: conversationIDs}, - (*pbmsg.SeqsInfoResp).GetMaxSeqs) + hasReadSeqs, err := c.msgClient.GetHasReadSeqs(ctx, conversationIDs, req.UserID) if err != nil { return nil, err } @@ -230,14 +238,7 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbconver return nil, errs.ErrArgs.WrapMsg("conversation must not be nil") } if req.Conversation.ConversationType == constant.WriteGroupChatType { - groupInfo, err := rpccall.ExtractField(ctx, pbgroup.GetGroupsInfoCaller.Invoke, - &pbgroup.GetGroupsInfoReq{GroupIDs: []string{req.Conversation.GroupID}}, - func(r *pbgroup.GetGroupsInfoResp) *sdkws.GroupInfo { - if len(r.GroupInfos) > 0 { - return r.GroupInfos[0] - } - return nil - }) + groupInfo, err := c.groupClient.GetGroupInfo(ctx, req.Conversation.GroupID) if err != nil { return nil, err } @@ -444,14 +445,14 @@ func (c *conversationServer) CreateGroupChatConversations(ctx context.Context, r return nil, err } conversationID := msgprocessor.GetConversationIDBySessionType(constant.ReadGroupChatType, req.GroupID) - if _, err := pbmsg.SetUserConversationMaxSeqCaller.Invoke(ctx, &pbmsg.SetUserConversationMaxSeqReq{ConversationID: conversationID, OwnerUserID: req.UserIDs, MaxSeq: 0}); err != nil { + if err := c.msgClient.SetUserConversationMaxSeq(ctx, conversationID, req.UserIDs, 0); err != nil { return nil, err } return &pbconversation.CreateGroupChatConversationsResp{}, nil } func (c *conversationServer) SetConversationMaxSeq(ctx context.Context, req *pbconversation.SetConversationMaxSeqReq) (*pbconversation.SetConversationMaxSeqResp, error) { - if _, err := pbmsg.SetUserConversationMaxSeqCaller.Invoke(ctx, &pbmsg.SetUserConversationMaxSeqReq{ConversationID: req.ConversationID, OwnerUserID: req.OwnerUserID, MaxSeq: req.MaxSeq}); err != nil { + if err := c.msgClient.SetUserConversationMaxSeq(ctx, req.ConversationID, req.OwnerUserID, req.MaxSeq); err != nil { return nil, err } if err := c.conversationDatabase.UpdateUsersConversationField(ctx, req.OwnerUserID, req.ConversationID, @@ -465,7 +466,7 @@ func (c *conversationServer) SetConversationMaxSeq(ctx context.Context, req *pbc } func (c *conversationServer) SetConversationMinSeq(ctx context.Context, req *pbconversation.SetConversationMinSeqReq) (*pbconversation.SetConversationMinSeqResp, error) { - if _, err := pbmsg.SetUserConversationMinSeqCaller.Invoke(ctx, &pbmsg.SetUserConversationMinSeqReq{ConversationID: req.ConversationID, OwnerUserID: req.OwnerUserID, MinSeq: req.MinSeq}); err != nil { + if err := c.msgClient.SetUserConversationMin(ctx, req.ConversationID, req.OwnerUserID, req.MinSeq); err != nil { return nil, err } if err := c.conversationDatabase.UpdateUsersConversationField(ctx, req.OwnerUserID, req.ConversationID, @@ -575,7 +576,7 @@ func (c *conversationServer) getConversationInfo( } } if len(sendIDs) != 0 { - sendInfos, err := rpcclient.GetUsersInfo(ctx, sendIDs) + sendInfos, err := c.userClient.GetUsersInfo(ctx, sendIDs) if err != nil { return nil, err } @@ -584,9 +585,7 @@ func (c *conversationServer) getConversationInfo( } } if len(groupIDs) != 0 { - groupInfos, err := rpccall.ExtractField(ctx, pbgroup.GetGroupsInfoCaller.Invoke, - &pbgroup.GetGroupsInfoReq{GroupIDs: groupIDs}, - (*pbgroup.GetGroupsInfoResp).GetGroupInfos) + groupInfos, err := c.groupClient.GetGroupsInfo(ctx, groupIDs) if err != nil { return nil, err } @@ -763,3 +762,51 @@ func (c *conversationServer) GetPinnedConversationIDs(ctx context.Context, req * } return &pbconversation.GetPinnedConversationIDsResp{ConversationIDs: conversationIDs}, nil } + +func (c *conversationServer) ClearUserConversationMsg(ctx context.Context, req *pbconversation.ClearUserConversationMsgReq) (*pbconversation.ClearUserConversationMsgResp, error) { + conversations, err := c.conversationDatabase.FindRandConversation(ctx, req.Timestamp, int(req.Limit)) + if err != nil { + return nil, err + } + latestMsgDestructTime := time.UnixMilli(req.Timestamp) + for i, conversation := range conversations { + if conversation.IsMsgDestruct == false || conversation.MsgDestructTime == 0 { + continue + } + seq, err := c.msgClient.GetLastMessageSeqByTime(ctx, conversation.ConversationID, req.Timestamp-conversation.MsgDestructTime) + if err != nil { + return nil, err + } + if seq <= 0 { + log.ZDebug(ctx, "ClearUserConversationMsg GetLastMessageSeqByTime seq <= 0", "index", i, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID, "msgDestructTime", conversation.MsgDestructTime, "seq", seq) + if err := c.setConversationMinSeqAndLatestMsgDestructTime(ctx, conversation.ConversationID, conversation.OwnerUserID, -1, latestMsgDestructTime); err != nil { + return nil, err + } + continue + } + seq++ + if err := c.setConversationMinSeqAndLatestMsgDestructTime(ctx, conversation.ConversationID, conversation.OwnerUserID, seq, latestMsgDestructTime); err != nil { + return nil, err + } + log.ZDebug(ctx, "ClearUserConversationMsg set min seq", "index", i, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID, "seq", seq, "msgDestructTime", conversation.MsgDestructTime) + } + return &pbconversation.ClearUserConversationMsgResp{Count: int32(len(conversations))}, nil +} + +func (c *conversationServer) setConversationMinSeqAndLatestMsgDestructTime(ctx context.Context, conversationID string, ownerUserID string, minSeq int64, latestMsgDestructTime time.Time) error { + update := map[string]any{ + "latest_msg_destruct_time": latestMsgDestructTime, + } + if minSeq >= 0 { + if err := c.msgClient.SetUserConversationMin(ctx, conversationID, []string{ownerUserID}, minSeq); err != nil { + return err + } + update["min_seq"] = minSeq + } + + if err := c.conversationDatabase.UpdateUsersConversationField(ctx, []string{ownerUserID}, conversationID, update); err != nil { + return err + } + c.conversationNotificationSender.ConversationChangeNotification(ctx, ownerUserID, []string{conversationID}) + return nil +} diff --git a/internal/rpc/conversation/notification.go b/internal/rpc/conversation/notification.go index f94c0cd07a..c6368b9166 100644 --- a/internal/rpc/conversation/notification.go +++ b/internal/rpc/conversation/notification.go @@ -16,9 +16,11 @@ package conversation import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" + "github.com/openimsdk/protocol/msg" "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" + "github.com/openimsdk/open-im-server/v3/pkg/notification" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/sdkws" ) @@ -27,8 +29,10 @@ type ConversationNotificationSender struct { *rpcclient.NotificationSender } -func NewConversationNotificationSender(conf *config.Notification) *ConversationNotificationSender { - return &ConversationNotificationSender{rpcclient.NewNotificationSender(conf, rpcclient.WithRpcClient())} +func NewConversationNotificationSender(conf *config.Notification, msgClient *rpcli.MsgClient) *ConversationNotificationSender { + return &ConversationNotificationSender{rpcclient.NewNotificationSender(conf, rpcclient.WithRpcClient(func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) { + return msgClient.SendMsg(ctx, req) + }))} } // SetPrivate invote. diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index 8af09b4c58..bea0e1af4d 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -17,6 +17,7 @@ package group import ( "context" "fmt" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "math/big" "math/rand" "strconv" @@ -35,14 +36,10 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/common/webhook" "github.com/openimsdk/open-im-server/v3/pkg/localcache" "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/grouphash" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification" + "github.com/openimsdk/open-im-server/v3/pkg/notification/grouphash" "github.com/openimsdk/protocol/constant" pbconv "github.com/openimsdk/protocol/conversation" pbgroup "github.com/openimsdk/protocol/group" - "github.com/openimsdk/protocol/msg" - "github.com/openimsdk/protocol/rpccall" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/protocol/wrapperspb" "github.com/openimsdk/tools/db/mongoutil" @@ -59,10 +56,13 @@ import ( type groupServer struct { pbgroup.UnimplementedGroupServer - db controller.GroupDatabase - notification *GroupNotificationSender - config *Config - webhookClient *webhook.Client + db controller.GroupDatabase + notification *NotificationSender + config *Config + webhookClient *webhook.Client + userClient *rpcli.UserClient + msgClient *rpcli.MsgClient + conversationClient *rpcli.ConversationClient } type Config struct { @@ -97,24 +97,33 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg if err != nil { return err } - var gs groupServer - database := controller.NewGroupDatabase(rdb, &config.LocalCacheConfig, groupDB, groupMemberDB, groupRequestDB, mgocli.GetTx(), grouphash.NewGroupHashFromGroupServer(&gs)) - gs.db = database - gs.notification = NewGroupNotificationSender( - database, - config, - func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) { - users, err := rpcclient.GetUsersInfo(ctx, userIDs) - if err != nil { - return nil, err - } - return datautil.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil - }, - ) + //userRpcClient := rpcclient.NewUserRpcClient(client, config.Share.RpcRegisterName.User, config.Share.IMAdminUserID) + //msgRpcClient := rpcclient.NewMessageRpcClient(client, config.Share.RpcRegisterName.Msg) + //conversationRpcClient := rpcclient.NewConversationRpcClient(client, config.Share.RpcRegisterName.Conversation) + + userConn, err := client.GetConn(ctx, config.Discovery.RpcService.User) + if err != nil { + return err + } + msgConn, err := client.GetConn(ctx, config.Discovery.RpcService.Msg) + if err != nil { + return err + } + conversationConn, err := client.GetConn(ctx, config.Discovery.RpcService.Conversation) + if err != nil { + return err + } + gs := groupServer{ + config: config, + webhookClient: webhook.NewWebhookClient(config.WebhooksConfig.URL), + userClient: rpcli.NewUserClient(userConn), + msgClient: rpcli.NewMsgClient(msgConn), + conversationClient: rpcli.NewConversationClient(conversationConn), + } + gs.db = controller.NewGroupDatabase(rdb, &config.LocalCacheConfig, groupDB, groupMemberDB, groupRequestDB, mgocli.GetTx(), grouphash.NewGroupHashFromGroupServer(&gs)) + gs.notification = NewNotificationSender(gs.db, config, gs.userClient, gs.msgClient, gs.conversationClient) localcache.InitLocalCache(&config.LocalCacheConfig) - gs.config = config - gs.webhookClient = webhook.NewWebhookClient(config.WebhooksConfig.URL) pbgroup.RegisterGroupServer(server, &gs) return nil } @@ -158,19 +167,6 @@ func (g *groupServer) CheckGroupAdmin(ctx context.Context, groupID string) error return nil } -func (g *groupServer) GetPublicUserInfoMap(ctx context.Context, userIDs []string) (map[string]*sdkws.PublicUserInfo, error) { - if len(userIDs) == 0 { - return map[string]*sdkws.PublicUserInfo{}, nil - } - users, err := rpcclient.GetPublicUserInfos(ctx, userIDs) - if err != nil { - return nil, err - } - return datautil.SliceToMapAny(users, func(e *sdkws.PublicUserInfo) (string, *sdkws.PublicUserInfo) { - return e.UserID, e - }), nil -} - func (g *groupServer) IsNotFound(err error) bool { return errs.ErrRecordNotFound.Is(specialerror.ErrCode(errs.Unwrap(err))) } @@ -212,7 +208,6 @@ func (g *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR return nil, errs.ErrArgs.WrapMsg("no group owner") } if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, g.config.Share.IMAdminUserID); err != nil { - return nil, err } userIDs := append(append(req.MemberUserIDs, req.AdminUserIDs...), req.OwnerUserID) @@ -225,7 +220,7 @@ func (g *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR return nil, errs.ErrArgs.WrapMsg("group member repeated") } - userMap, err := rpcclient.GetUsersInfoMap(ctx, userIDs) + userMap, err := g.userClient.GetUsersInfoMap(ctx, userIDs) if err != nil { return nil, err } @@ -376,7 +371,7 @@ func (g *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite return nil, servererrs.ErrDismissedAlready.WrapMsg("group dismissed checking group status found it dismissed") } - userMap, err := rpcclient.GetUsersInfoMap(ctx, req.InvitedUserIDs) + userMap, err := g.userClient.GetUsersInfoMap(ctx, req.InvitedUserIDs) if err != nil { return nil, err } @@ -687,7 +682,7 @@ func (g *groupServer) GetGroupApplicationList(ctx context.Context, req *pbgroup. userIDs = append(userIDs, gr.UserID) } userIDs = datautil.Distinct(userIDs) - userMap, err := rpcclient.GetPublicUserInfoMap(ctx, userIDs) + userMap, err := g.userClient.GetUsersInfoMap(ctx, userIDs) if err != nil { return nil, err } @@ -799,7 +794,7 @@ func (g *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup } else if !g.IsNotFound(err) { return nil, err } - if _, err := rpcclient.GetPublicUserInfo(ctx, req.FromUserID); err != nil { + if err := g.userClient.CheckUser(ctx, []string{req.FromUserID}); err != nil { return nil, err } var member *model.GroupMember @@ -843,7 +838,7 @@ func (g *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup } func (g *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq) (*pbgroup.JoinGroupResp, error) { - user, err := rpcclient.GetUserInfo(ctx, req.InviterUserID) + user, err := g.userClient.GetUserInfo(ctx, req.InviterUserID) if err != nil { return nil, err } @@ -950,18 +945,11 @@ func (g *groupServer) QuitGroup(ctx context.Context, req *pbgroup.QuitGroupReq) func (g *groupServer) deleteMemberAndSetConversationSeq(ctx context.Context, groupID string, userIDs []string) error { conversationID := msgprocessor.GetConversationIDBySessionType(constant.ReadGroupChatType, groupID) - maxSeq, err := rpccall.ExtractField(ctx, msg.GetConversationMaxSeqCaller.Invoke, - &msg.GetConversationMaxSeqReq{ConversationID: conversationID}, - (*msg.GetConversationMaxSeqResp).GetMaxSeq) + maxSeq, err := g.msgClient.GetConversationMaxSeq(ctx, conversationID) if err != nil { return err } - - return pbconv.SetConversationMaxSeqCaller.Execute(ctx, &pbconv.SetConversationMaxSeqReq{ - ConversationID: conversationID, - OwnerUserID: userIDs, - MaxSeq: maxSeq, - }) + return g.conversationClient.SetConversationMaxSeq(ctx, conversationID, userIDs, maxSeq) } func (g *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInfoReq) (*pbgroup.SetGroupInfoResp, error) { @@ -1037,11 +1025,7 @@ func (g *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInf return } conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.GroupNotification} - - if err := pbconv.SetConversationsCaller.Execute(ctx, &pbconv.SetConversationsReq{ - UserIDs: resp.UserIDs, - Conversation: conversation, - }); err != nil { + if err := g.conversationClient.SetConversations(ctx, resp.UserIDs, conversation); err != nil { log.ZWarn(ctx, "SetConversations", err, "UserIDs", resp.UserIDs, "conversation", conversation) } }() @@ -1154,11 +1138,7 @@ func (g *groupServer) SetGroupInfoEx(ctx context.Context, req *pbgroup.SetGroupI } conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.GroupNotification} - - if err := pbconv.SetConversationsCaller.Execute(ctx, &pbconv.SetConversationsReq{ - UserIDs: resp.UserIDs, - Conversation: conversation, - }); err != nil { + if err := g.conversationClient.SetConversations(ctx, resp.UserIDs, conversation); err != nil { log.ZWarn(ctx, "SetConversations", err, "UserIDs", resp.UserIDs, "conversation", conversation) } }() @@ -1310,7 +1290,7 @@ func (g *groupServer) GetGroupMembersCMS(ctx context.Context, req *pbgroup.GetGr } func (g *groupServer) GetUserReqApplicationList(ctx context.Context, req *pbgroup.GetUserReqApplicationListReq) (*pbgroup.GetUserReqApplicationListResp, error) { - user, err := rpcclient.GetPublicUserInfo(ctx, req.UserID) + user, err := g.userClient.GetUserInfo(ctx, req.UserID) if err != nil { return nil, err } @@ -1766,7 +1746,7 @@ func (g *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req * return nil, servererrs.ErrGroupIDNotFound.WrapMsg(strings.Join(ids, ",")) } - userMap, err := rpcclient.GetPublicUserInfoMap(ctx, req.UserIDs) + userMap, err := g.userClient.GetUsersInfoMap(ctx, req.UserIDs) if err != nil { return nil, err } @@ -1797,7 +1777,7 @@ func (g *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req * ownerUserID = owner.UserID } - var userInfo *sdkws.PublicUserInfo + var userInfo *sdkws.UserInfo if user, ok := userMap[e.UserID]; !ok { userInfo = user } @@ -1843,7 +1823,7 @@ func (g *groupServer) GetSpecifiedUserGroupRequestInfo(ctx context.Context, req return nil, err } - userInfos, err := rpcclient.GetPublicUserInfos(ctx, []string{req.UserID}) + userInfos, err := g.userClient.GetUsersInfo(ctx, []string{req.UserID}) if err != nil { return nil, err } diff --git a/internal/rpc/group/notification.go b/internal/rpc/group/notification.go index 784ec89434..48fadbd07c 100644 --- a/internal/rpc/group/notification.go +++ b/internal/rpc/group/notification.go @@ -18,6 +18,7 @@ import ( "context" "errors" "fmt" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "time" "github.com/openimsdk/open-im-server/v3/pkg/authverify" @@ -28,13 +29,11 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/versionctx" "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification" + "github.com/openimsdk/open-im-server/v3/pkg/notification" + "github.com/openimsdk/open-im-server/v3/pkg/notification/common_user" "github.com/openimsdk/protocol/constant" - pbconv "github.com/openimsdk/protocol/conversation" pbgroup "github.com/openimsdk/protocol/group" "github.com/openimsdk/protocol/msg" - "github.com/openimsdk/protocol/rpccall" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" @@ -50,27 +49,38 @@ const ( adminReceiver ) -func NewGroupNotificationSender( - db controller.GroupDatabase, - config *Config, - fn func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error), -) *GroupNotificationSender { - return &GroupNotificationSender{ - NotificationSender: rpcclient.NewNotificationSender(&config.NotificationConfig, rpcclient.WithRpcClient(), rpcclient.WithUserRpcClient()), - getUsersInfo: fn, +func NewNotificationSender(db controller.GroupDatabase, config *Config, userClient *rpcli.UserClient, msgClient *rpcli.MsgClient, conversationClient *rpcli.ConversationClient) *NotificationSender { + return &NotificationSender{ + NotificationSender: rpcclient.NewNotificationSender(&config.NotificationConfig, + rpcclient.WithRpcClient(func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) { + return msgClient.SendMsg(ctx, req) + }), + rpcclient.WithUserRpcClient(userClient.GetUserInfo), + ), + getUsersInfo: func(ctx context.Context, userIDs []string) ([]common_user.CommonUser, error) { + users, err := userClient.GetUsersInfo(ctx, userIDs) + if err != nil { + return nil, err + } + return datautil.Slice(users, func(e *sdkws.UserInfo) common_user.CommonUser { return e }), nil + }, db: db, config: config, + msgClient: msgClient, + conversationClient: conversationClient, } } -type GroupNotificationSender struct { +type NotificationSender struct { *rpcclient.NotificationSender - getUsersInfo func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) - db controller.GroupDatabase - config *Config + getUsersInfo func(ctx context.Context, userIDs []string) ([]common_user.CommonUser, error) + db controller.GroupDatabase + config *Config + msgClient *rpcli.MsgClient + conversationClient *rpcli.ConversationClient } -func (g *GroupNotificationSender) PopulateGroupMember(ctx context.Context, members ...*model.GroupMember) error { +func (g *NotificationSender) PopulateGroupMember(ctx context.Context, members ...*model.GroupMember) error { if len(members) == 0 { return nil } @@ -85,7 +95,7 @@ func (g *GroupNotificationSender) PopulateGroupMember(ctx context.Context, membe if err != nil { return err } - userMap := make(map[string]notification.CommonUser) + userMap := make(map[string]common_user.CommonUser) for i, user := range users { userMap[user.GetUserID()] = users[i] } @@ -105,7 +115,7 @@ func (g *GroupNotificationSender) PopulateGroupMember(ctx context.Context, membe return nil } -func (g *GroupNotificationSender) getUser(ctx context.Context, userID string) (*sdkws.PublicUserInfo, error) { +func (g *NotificationSender) getUser(ctx context.Context, userID string) (*sdkws.PublicUserInfo, error) { users, err := g.getUsersInfo(ctx, []string{userID}) if err != nil { return nil, err @@ -121,7 +131,7 @@ func (g *GroupNotificationSender) getUser(ctx context.Context, userID string) (* }, nil } -func (g *GroupNotificationSender) getGroupInfo(ctx context.Context, groupID string) (*sdkws.GroupInfo, error) { +func (g *NotificationSender) getGroupInfo(ctx context.Context, groupID string) (*sdkws.GroupInfo, error) { gm, err := g.db.TakeGroup(ctx, groupID) if err != nil { return nil, err @@ -142,7 +152,7 @@ func (g *GroupNotificationSender) getGroupInfo(ctx context.Context, groupID stri return convert.Db2PbGroupInfo(gm, ownerUserID, num), nil } -func (g *GroupNotificationSender) getGroupMembers(ctx context.Context, groupID string, userIDs []string) ([]*sdkws.GroupMemberFullInfo, error) { +func (g *NotificationSender) getGroupMembers(ctx context.Context, groupID string, userIDs []string) ([]*sdkws.GroupMemberFullInfo, error) { members, err := g.db.FindGroupMembers(ctx, groupID, userIDs) if err != nil { return nil, err @@ -158,7 +168,7 @@ func (g *GroupNotificationSender) getGroupMembers(ctx context.Context, groupID s return res, nil } -func (g *GroupNotificationSender) getGroupMemberMap(ctx context.Context, groupID string, userIDs []string) (map[string]*sdkws.GroupMemberFullInfo, error) { +func (g *NotificationSender) getGroupMemberMap(ctx context.Context, groupID string, userIDs []string) (map[string]*sdkws.GroupMemberFullInfo, error) { members, err := g.getGroupMembers(ctx, groupID, userIDs) if err != nil { return nil, err @@ -170,7 +180,7 @@ func (g *GroupNotificationSender) getGroupMemberMap(ctx context.Context, groupID return m, nil } -func (g *GroupNotificationSender) getGroupMember(ctx context.Context, groupID string, userID string) (*sdkws.GroupMemberFullInfo, error) { +func (g *NotificationSender) getGroupMember(ctx context.Context, groupID string, userID string) (*sdkws.GroupMemberFullInfo, error) { members, err := g.getGroupMembers(ctx, groupID, []string{userID}) if err != nil { return nil, err @@ -181,7 +191,7 @@ func (g *GroupNotificationSender) getGroupMember(ctx context.Context, groupID st return members[0], nil } -func (g *GroupNotificationSender) getGroupOwnerAndAdminUserID(ctx context.Context, groupID string) ([]string, error) { +func (g *NotificationSender) getGroupOwnerAndAdminUserID(ctx context.Context, groupID string) ([]string, error) { members, err := g.db.FindGroupMemberRoleLevels(ctx, groupID, []int32{constant.GroupOwner, constant.GroupAdmin}) if err != nil { return nil, err @@ -193,7 +203,7 @@ func (g *GroupNotificationSender) getGroupOwnerAndAdminUserID(ctx context.Contex return datautil.Slice(members, fn), nil } -func (g *GroupNotificationSender) groupMemberDB2PB(member *model.GroupMember, appMangerLevel int32) *sdkws.GroupMemberFullInfo { +func (g *NotificationSender) groupMemberDB2PB(member *model.GroupMember, appMangerLevel int32) *sdkws.GroupMemberFullInfo { return &sdkws.GroupMemberFullInfo{ GroupID: member.GroupID, UserID: member.UserID, @@ -210,7 +220,7 @@ func (g *GroupNotificationSender) groupMemberDB2PB(member *model.GroupMember, ap } } -/* func (g *GroupNotificationSender) getUsersInfoMap(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error) { +/* func (g *NotificationSender) getUsersInfoMap(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error) { users, err := g.getUsersInfo(ctx, userIDs) if err != nil { return nil, err @@ -222,11 +232,11 @@ func (g *GroupNotificationSender) groupMemberDB2PB(member *model.GroupMember, ap return result, nil } */ -func (g *GroupNotificationSender) fillOpUser(ctx context.Context, opUser **sdkws.GroupMemberFullInfo, groupID string) (err error) { +func (g *NotificationSender) fillOpUser(ctx context.Context, opUser **sdkws.GroupMemberFullInfo, groupID string) (err error) { return g.fillOpUserByUserID(ctx, mcontext.GetOpUserID(ctx), opUser, groupID) } -func (g *GroupNotificationSender) fillOpUserByUserID(ctx context.Context, userID string, opUser **sdkws.GroupMemberFullInfo, groupID string) error { +func (g *NotificationSender) fillOpUserByUserID(ctx context.Context, userID string, opUser **sdkws.GroupMemberFullInfo, groupID string) error { if opUser == nil { return errs.ErrInternalServer.WrapMsg("**sdkws.GroupMemberFullInfo is nil") } @@ -270,7 +280,7 @@ func (g *GroupNotificationSender) fillOpUserByUserID(ctx context.Context, userID return nil } -func (g *GroupNotificationSender) setVersion(ctx context.Context, version *uint64, versionID *string, collName string, id string) { +func (g *NotificationSender) setVersion(ctx context.Context, version *uint64, versionID *string, collName string, id string) { versions := versionctx.GetVersionLog(ctx).Get() for _, coll := range versions { if coll.Name == collName && coll.Doc.DID == id { @@ -281,7 +291,7 @@ func (g *GroupNotificationSender) setVersion(ctx context.Context, version *uint6 } } -func (g *GroupNotificationSender) setSortVersion(ctx context.Context, version *uint64, versionID *string, collName string, id string, sortVersion *uint64) { +func (g *NotificationSender) setSortVersion(ctx context.Context, version *uint64, versionID *string, collName string, id string, sortVersion *uint64) { versions := versionctx.GetVersionLog(ctx).Get() for _, coll := range versions { if coll.Name == collName && coll.Doc.DID == id { @@ -296,7 +306,7 @@ func (g *GroupNotificationSender) setSortVersion(ctx context.Context, version *u } } -func (g *GroupNotificationSender) GroupCreatedNotification(ctx context.Context, tips *sdkws.GroupCreatedTips) { +func (g *NotificationSender) GroupCreatedNotification(ctx context.Context, tips *sdkws.GroupCreatedTips) { var err error defer func() { if err != nil { @@ -310,7 +320,7 @@ func (g *GroupNotificationSender) GroupCreatedNotification(ctx context.Context, g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupCreatedNotification, tips) } -func (g *GroupNotificationSender) GroupInfoSetNotification(ctx context.Context, tips *sdkws.GroupInfoSetTips) { +func (g *NotificationSender) GroupInfoSetNotification(ctx context.Context, tips *sdkws.GroupInfoSetTips) { var err error defer func() { if err != nil { @@ -324,7 +334,7 @@ func (g *GroupNotificationSender) GroupInfoSetNotification(ctx context.Context, g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetNotification, tips, rpcclient.WithRpcGetUserName()) } -func (g *GroupNotificationSender) GroupInfoSetNameNotification(ctx context.Context, tips *sdkws.GroupInfoSetNameTips) { +func (g *NotificationSender) GroupInfoSetNameNotification(ctx context.Context, tips *sdkws.GroupInfoSetNameTips) { var err error defer func() { if err != nil { @@ -338,7 +348,7 @@ func (g *GroupNotificationSender) GroupInfoSetNameNotification(ctx context.Conte g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetNameNotification, tips) } -func (g *GroupNotificationSender) GroupInfoSetAnnouncementNotification(ctx context.Context, tips *sdkws.GroupInfoSetAnnouncementTips) { +func (g *NotificationSender) GroupInfoSetAnnouncementNotification(ctx context.Context, tips *sdkws.GroupInfoSetAnnouncementTips) { var err error defer func() { if err != nil { @@ -352,7 +362,7 @@ func (g *GroupNotificationSender) GroupInfoSetAnnouncementNotification(ctx conte g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetAnnouncementNotification, tips, rpcclient.WithRpcGetUserName()) } -func (g *GroupNotificationSender) JoinGroupApplicationNotification(ctx context.Context, req *pbgroup.JoinGroupReq) { +func (g *NotificationSender) JoinGroupApplicationNotification(ctx context.Context, req *pbgroup.JoinGroupReq) { var err error defer func() { if err != nil { @@ -380,7 +390,7 @@ func (g *GroupNotificationSender) JoinGroupApplicationNotification(ctx context.C } } -func (g *GroupNotificationSender) MemberQuitNotification(ctx context.Context, member *sdkws.GroupMemberFullInfo) { +func (g *NotificationSender) MemberQuitNotification(ctx context.Context, member *sdkws.GroupMemberFullInfo) { var err error defer func() { if err != nil { @@ -397,7 +407,7 @@ func (g *GroupNotificationSender) MemberQuitNotification(ctx context.Context, me g.Notification(ctx, mcontext.GetOpUserID(ctx), member.GroupID, constant.MemberQuitNotification, tips) } -func (g *GroupNotificationSender) GroupApplicationAcceptedNotification(ctx context.Context, req *pbgroup.GroupApplicationResponseReq) { +func (g *NotificationSender) GroupApplicationAcceptedNotification(ctx context.Context, req *pbgroup.GroupApplicationResponseReq) { var err error defer func() { if err != nil { @@ -430,7 +440,7 @@ func (g *GroupNotificationSender) GroupApplicationAcceptedNotification(ctx conte } } -func (g *GroupNotificationSender) GroupApplicationRejectedNotification(ctx context.Context, req *pbgroup.GroupApplicationResponseReq) { +func (g *NotificationSender) GroupApplicationRejectedNotification(ctx context.Context, req *pbgroup.GroupApplicationResponseReq) { var err error defer func() { if err != nil { @@ -463,7 +473,7 @@ func (g *GroupNotificationSender) GroupApplicationRejectedNotification(ctx conte } } -func (g *GroupNotificationSender) GroupOwnerTransferredNotification(ctx context.Context, req *pbgroup.TransferGroupOwnerReq) { +func (g *NotificationSender) GroupOwnerTransferredNotification(ctx context.Context, req *pbgroup.TransferGroupOwnerReq) { var err error defer func() { if err != nil { @@ -494,7 +504,7 @@ func (g *GroupNotificationSender) GroupOwnerTransferredNotification(ctx context. g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupOwnerTransferredNotification, tips) } -func (g *GroupNotificationSender) MemberKickedNotification(ctx context.Context, tips *sdkws.MemberKickedTips) { +func (g *NotificationSender) MemberKickedNotification(ctx context.Context, tips *sdkws.MemberKickedTips) { var err error defer func() { if err != nil { @@ -508,7 +518,7 @@ func (g *GroupNotificationSender) MemberKickedNotification(ctx context.Context, g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.MemberKickedNotification, tips) } -func (g *GroupNotificationSender) GroupApplicationAgreeMemberEnterNotification(ctx context.Context, groupID string, invitedOpUserID string, entrantUserID ...string) error { +func (g *NotificationSender) GroupApplicationAgreeMemberEnterNotification(ctx context.Context, groupID string, invitedOpUserID string, entrantUserID ...string) error { var err error defer func() { if err != nil { @@ -518,26 +528,15 @@ func (g *GroupNotificationSender) GroupApplicationAgreeMemberEnterNotification(c if !g.config.RpcConfig.EnableHistoryForNewMembers { conversationID := msgprocessor.GetConversationIDBySessionType(constant.ReadGroupChatType, groupID) - maxSeq, err := rpccall.ExtractField(ctx, msg.GetConversationMaxSeqCaller.Invoke, - &msg.GetConversationMaxSeqReq{ConversationID: conversationID}, - (*msg.GetConversationMaxSeqResp).GetMaxSeq) + maxSeq, err := g.msgClient.GetConversationMaxSeq(ctx, conversationID) if err != nil { return err } - - if err := msg.SetUserConversationsMinSeqCaller.Execute(ctx, &msg.SetUserConversationsMinSeqReq{ - UserIDs: entrantUserID, - ConversationID: conversationID, - Seq: maxSeq, - }); err != nil { + if err := g.msgClient.SetUserConversationsMinSeq(ctx, conversationID, entrantUserID, maxSeq); err != nil { return err } } - - if err := pbconv.CreateGroupChatConversationsCaller.Execute(ctx, &pbconv.CreateGroupChatConversationsReq{ - UserIDs: entrantUserID, - GroupID: groupID, - }); err != nil { + if err := g.conversationClient.CreateGroupChatConversations(ctx, groupID, entrantUserID); err != nil { return err } @@ -573,7 +572,7 @@ func (g *GroupNotificationSender) GroupApplicationAgreeMemberEnterNotification(c return nil } -func (g *GroupNotificationSender) MemberEnterNotification(ctx context.Context, groupID string, entrantUserID string) error { +func (g *NotificationSender) MemberEnterNotification(ctx context.Context, groupID string, entrantUserID string) error { var err error defer func() { if err != nil { @@ -583,28 +582,17 @@ func (g *GroupNotificationSender) MemberEnterNotification(ctx context.Context, g if !g.config.RpcConfig.EnableHistoryForNewMembers { conversationID := msgprocessor.GetConversationIDBySessionType(constant.ReadGroupChatType, groupID) - maxSeq, err := rpccall.ExtractField(ctx, msg.GetConversationMaxSeqCaller.Invoke, - &msg.GetConversationMaxSeqReq{ConversationID: conversationID}, - (*msg.GetConversationMaxSeqResp).GetMaxSeq) + maxSeq, err := g.msgClient.GetConversationMaxSeq(ctx, conversationID) if err != nil { return err } - if err := msg.SetUserConversationsMinSeqCaller.Execute(ctx, &msg.SetUserConversationsMinSeqReq{ - UserIDs: []string{entrantUserID}, - ConversationID: conversationID, - Seq: maxSeq, - }); err != nil { + if err := g.msgClient.SetUserConversationsMinSeq(ctx, conversationID, []string{entrantUserID}, maxSeq); err != nil { return err } } - - if err := pbconv.CreateGroupChatConversationsCaller.Execute(ctx, &pbconv.CreateGroupChatConversationsReq{ - UserIDs: []string{entrantUserID}, - GroupID: groupID, - }); err != nil { + if err := g.conversationClient.CreateGroupChatConversations(ctx, groupID, []string{entrantUserID}); err != nil { return err } - var group *sdkws.GroupInfo group, err = g.getGroupInfo(ctx, groupID) if err != nil { @@ -625,7 +613,7 @@ func (g *GroupNotificationSender) MemberEnterNotification(ctx context.Context, g return nil } -func (g *GroupNotificationSender) GroupDismissedNotification(ctx context.Context, tips *sdkws.GroupDismissedTips) { +func (g *NotificationSender) GroupDismissedNotification(ctx context.Context, tips *sdkws.GroupDismissedTips) { var err error defer func() { if err != nil { @@ -638,7 +626,7 @@ func (g *GroupNotificationSender) GroupDismissedNotification(ctx context.Context g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupDismissedNotification, tips) } -func (g *GroupNotificationSender) GroupMemberMutedNotification(ctx context.Context, groupID, groupMemberUserID string, mutedSeconds uint32) { +func (g *NotificationSender) GroupMemberMutedNotification(ctx context.Context, groupID, groupMemberUserID string, mutedSeconds uint32) { var err error defer func() { if err != nil { @@ -666,7 +654,7 @@ func (g *GroupNotificationSender) GroupMemberMutedNotification(ctx context.Conte g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberMutedNotification, tips) } -func (g *GroupNotificationSender) GroupMemberCancelMutedNotification(ctx context.Context, groupID, groupMemberUserID string) { +func (g *NotificationSender) GroupMemberCancelMutedNotification(ctx context.Context, groupID, groupMemberUserID string) { var err error defer func() { if err != nil { @@ -691,7 +679,7 @@ func (g *GroupNotificationSender) GroupMemberCancelMutedNotification(ctx context g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberCancelMutedNotification, tips) } -func (g *GroupNotificationSender) GroupMutedNotification(ctx context.Context, groupID string) { +func (g *NotificationSender) GroupMutedNotification(ctx context.Context, groupID string) { var err error defer func() { if err != nil { @@ -719,7 +707,7 @@ func (g *GroupNotificationSender) GroupMutedNotification(ctx context.Context, gr g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMutedNotification, tips) } -func (g *GroupNotificationSender) GroupCancelMutedNotification(ctx context.Context, groupID string) { +func (g *NotificationSender) GroupCancelMutedNotification(ctx context.Context, groupID string) { var err error defer func() { if err != nil { @@ -747,7 +735,7 @@ func (g *GroupNotificationSender) GroupCancelMutedNotification(ctx context.Conte g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupCancelMutedNotification, tips) } -func (g *GroupNotificationSender) GroupMemberInfoSetNotification(ctx context.Context, groupID, groupMemberUserID string) { +func (g *NotificationSender) GroupMemberInfoSetNotification(ctx context.Context, groupID, groupMemberUserID string) { var err error defer func() { if err != nil { @@ -772,7 +760,7 @@ func (g *GroupNotificationSender) GroupMemberInfoSetNotification(ctx context.Con g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberInfoSetNotification, tips) } -func (g *GroupNotificationSender) GroupMemberSetToAdminNotification(ctx context.Context, groupID, groupMemberUserID string) { +func (g *NotificationSender) GroupMemberSetToAdminNotification(ctx context.Context, groupID, groupMemberUserID string) { var err error defer func() { if err != nil { @@ -796,7 +784,7 @@ func (g *GroupNotificationSender) GroupMemberSetToAdminNotification(ctx context. g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToAdminNotification, tips) } -func (g *GroupNotificationSender) GroupMemberSetToOrdinaryUserNotification(ctx context.Context, groupID, groupMemberUserID string) { +func (g *NotificationSender) GroupMemberSetToOrdinaryUserNotification(ctx context.Context, groupID, groupMemberUserID string) { var err error defer func() { if err != nil { diff --git a/internal/rpc/msg/clear.go b/internal/rpc/msg/clear.go index 7d62e7c8fa..8e14b281e7 100644 --- a/internal/rpc/msg/clear.go +++ b/internal/rpc/msg/clear.go @@ -2,138 +2,59 @@ package msg import ( "context" - "time" - "github.com/openimsdk/open-im-server/v3/pkg/authverify" - "github.com/openimsdk/open-im-server/v3/pkg/common/convert" - pbconv "github.com/openimsdk/protocol/conversation" "github.com/openimsdk/protocol/msg" - "github.com/openimsdk/protocol/wrapperspb" - "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" - "github.com/openimsdk/tools/mcontext" - "github.com/openimsdk/tools/utils/datautil" - "github.com/openimsdk/tools/utils/idutil" - "github.com/openimsdk/tools/utils/stringutil" - "golang.org/x/sync/errgroup" + "strings" ) -// hard delete in Database. -func (m *msgServer) DestructMsgs(ctx context.Context, req *msg.DestructMsgsReq) (_ *msg.DestructMsgsResp, err error) { +// DestructMsgs hard delete in Database. +func (m *msgServer) DestructMsgs(ctx context.Context, req *msg.DestructMsgsReq) (*msg.DestructMsgsResp, error) { if err := authverify.CheckAdmin(ctx, m.config.Share.IMAdminUserID); err != nil { return nil, err } - if req.Timestamp > time.Now().UnixMilli() { - return nil, errs.ErrArgs.WrapMsg("request millisecond timestamp error") + docs, err := m.MsgDatabase.GetRandBeforeMsg(ctx, req.Timestamp, int(req.Limit)) + if err != nil { + return nil, err } - var ( - docNum int - msgNum int - start = time.Now() - getLimit = 5000 - ) - - destructMsg := func(ctx context.Context) (bool, error) { - docIDs, err := m.MsgDatabase.GetDocIDs(ctx) - if err != nil { - return false, err + for i, doc := range docs { + if err := m.MsgDatabase.DeleteDoc(ctx, doc.DocID); err != nil { + return nil, err } - - msgs, err := m.MsgDatabase.GetBeforeMsg(ctx, req.Timestamp, docIDs, getLimit) - if err != nil { - return false, err - } - if len(msgs) == 0 { - return false, nil + log.ZDebug(ctx, "DestructMsgs delete doc", "index", i, "docID", doc.DocID) + index := strings.LastIndex(doc.DocID, ":") + if index < 0 { + continue } - - for _, msg := range msgs { - index, err := m.MsgDatabase.DeleteDocMsgBefore(ctx, req.Timestamp, msg) - if err != nil { - return false, err + var minSeq int64 + for _, model := range doc.Msg { + if model.Msg == nil { + continue } - if len(index) == 0 { - return false, errs.ErrInternalServer.WrapMsg("delete doc msg failed") + if model.Msg.Seq > minSeq { + minSeq = model.Msg.Seq } - - docNum++ - msgNum += len(index) } - - return true, nil - } - - _, err = destructMsg(ctx) - if err != nil { - log.ZError(ctx, "clear msg failed", err, "docNum", docNum, "msgNum", msgNum, "cost", time.Since(start)) - return nil, err + if minSeq <= 0 { + continue + } + conversationID := doc.DocID[:index] + if conversationID == "" { + continue + } + minSeq++ + if err := m.MsgDatabase.SetMinSeq(ctx, conversationID, minSeq); err != nil { + return nil, err + } + log.ZDebug(ctx, "DestructMsgs delete doc set min seq", "index", i, "docID", doc.DocID, "conversationID", conversationID, "setMinSeq", minSeq) } - - log.ZDebug(ctx, "clearing message", "docNum", docNum, "msgNum", msgNum, "cost", time.Since(start)) - - return &msg.DestructMsgsResp{}, nil + return &msg.DestructMsgsResp{Count: int32(len(docs))}, nil } -// soft delete for user self -func (m *msgServer) ClearMsg(ctx context.Context, req *msg.ClearMsgReq) (_ *msg.ClearMsgResp, err error) { - temp := convert.ConversationsPb2DB(req.Conversations) - - batchNum := 100 - - errg, _ := errgroup.WithContext(ctx) - errg.SetLimit(100) - - for i := 0; i < len(temp); i += batchNum { - batch := temp[i:min(i+batchNum, len(temp))] - - errg.Go(func() error { - for _, conversation := range batch { - handleCtx := mcontext.NewCtx(stringutil.GetSelfFuncName() + "-" + idutil.OperationIDGenerator() + "-" + conversation.ConversationID + "-" + conversation.OwnerUserID) - log.ZDebug(handleCtx, "User MsgsDestruct", - "conversationID", conversation.ConversationID, - "ownerUserID", conversation.OwnerUserID, - "msgDestructTime", conversation.MsgDestructTime, - "lastMsgDestructTime", conversation.LatestMsgDestructTime) - - seqs, err := m.MsgDatabase.ClearUserMsgs(handleCtx, conversation.OwnerUserID, conversation.ConversationID, conversation.MsgDestructTime, conversation.LatestMsgDestructTime) - if err != nil { - log.ZError(handleCtx, "user msg destruct failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID) - continue - } - - if len(seqs) > 0 { - minseq := datautil.Max(seqs...) - - // update - if err := pbconv.UpdateConversationCaller.Execute(ctx, &pbconv.UpdateConversationReq{ - ConversationID: conversation.ConversationID, - UserIDs: []string{conversation.OwnerUserID}, - MinSeq: wrapperspb.Int64(minseq), - LatestMsgDestructTime: wrapperspb.Int64(time.Now().UnixMilli()), - }); err != nil { - log.ZError(handleCtx, "updateUsersConversationField failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID) - continue - } - - if err := pbconv.SetConversationMinSeqCaller.Execute(ctx, &pbconv.SetConversationMinSeqReq{ - ConversationID: conversation.ConversationID, - OwnerUserID: []string{conversation.OwnerUserID}, - MinSeq: minseq, - }); err != nil { - return err - } - - // if you need Notify SDK client userseq is update. - // m.msgNotificationSender.UserDeleteMsgsNotification(handleCtx, conversation.OwnerUserID, conversation.ConversationID, seqs) - } - } - return nil - }) - } - - if err := errg.Wait(); err != nil { +func (m *msgServer) GetLastMessageSeqByTime(ctx context.Context, req *msg.GetLastMessageSeqByTimeReq) (*msg.GetLastMessageSeqByTimeResp, error) { + seq, err := m.MsgDatabase.GetLastMessageSeqByTime(ctx, req.ConversationID, req.Time) + if err != nil { return nil, err } - - return nil, nil + return &msg.GetLastMessageSeqByTimeResp{Seq: seq}, nil } diff --git a/internal/rpc/msg/delete.go b/internal/rpc/msg/delete.go index e0c3a89ed8..f45713ff12 100644 --- a/internal/rpc/msg/delete.go +++ b/internal/rpc/msg/delete.go @@ -21,7 +21,6 @@ import ( "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/conversation" "github.com/openimsdk/protocol/msg" - "github.com/openimsdk/protocol/rpccall" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/utils/timeutil" @@ -75,22 +74,13 @@ func (m *msgServer) DeleteMsgs(ctx context.Context, req *msg.DeleteMsgsReq) (*ms if err := m.MsgDatabase.DeleteMsgsPhysicalBySeqs(ctx, req.ConversationID, req.Seqs); err != nil { return nil, err } - - conversations, err := rpccall.ExtractField(ctx, conversation.GetConversationsByConversationIDCaller.Invoke, &conversation.GetConversationsByConversationIDReq{ - ConversationIDs: []string{req.ConversationID}, - }, (*conversation.GetConversationsByConversationIDResp).GetConversations) + conv, err := m.conversationClient.GetConversationsByConversationID(ctx, req.ConversationID) if err != nil { return nil, err } tips := &sdkws.DeleteMsgsTips{UserID: req.UserID, ConversationID: req.ConversationID, Seqs: req.Seqs} - m.notificationSender.NotificationWithSessionType( - ctx, - req.UserID, - m.conversationAndGetRecvID(conversations[0], req.UserID), - constant.DeleteMsgsNotification, - conversations[0].ConversationType, - tips, - ) + m.notificationSender.NotificationWithSessionType(ctx, req.UserID, m.conversationAndGetRecvID(conv, req.UserID), + constant.DeleteMsgsNotification, conv.ConversationType, tips) } else { if err := m.MsgDatabase.DeleteUserMsgsBySeqs(ctx, req.UserID, req.ConversationID, req.Seqs); err != nil { return nil, err @@ -125,9 +115,7 @@ func (m *msgServer) DeleteMsgPhysical(ctx context.Context, req *msg.DeleteMsgPhy } func (m *msgServer) clearConversation(ctx context.Context, conversationIDs []string, userID string, deleteSyncOpt *msg.DeleteSyncOpt) error { - conversations, err := rpccall.ExtractField(ctx, conversation.GetConversationsByConversationIDCaller.Invoke, &conversation.GetConversationsByConversationIDReq{ - ConversationIDs: conversationIDs, - }, (*conversation.GetConversationsByConversationIDResp).GetConversations) + conversations, err := m.conversationClient.GetConversationsByConversationIDs(ctx, conversationIDs) if err != nil { return err } @@ -150,11 +138,7 @@ func (m *msgServer) clearConversation(ctx context.Context, conversationIDs []str } ownerUserIDs := []string{userID} for conversationID, seq := range setSeqs { - if err := conversation.SetConversationMinSeqCaller.Execute(ctx, &conversation.SetConversationMinSeqReq{ - ConversationID: conversationID, - OwnerUserID: ownerUserIDs, - MinSeq: seq, - }); err != nil { + if err := m.conversationClient.SetConversationMinSeq(ctx, conversationID, ownerUserIDs, seq); err != nil { return err } } diff --git a/internal/rpc/msg/notification.go b/internal/rpc/msg/notification.go index 26e3c7f46a..14576f693a 100644 --- a/internal/rpc/msg/notification.go +++ b/internal/rpc/msg/notification.go @@ -17,7 +17,7 @@ package msg import ( "context" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" + "github.com/openimsdk/open-im-server/v3/pkg/notification" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/sdkws" ) diff --git a/internal/rpc/msg/send.go b/internal/rpc/msg/send.go index bb20206f7a..b9bbf615f3 100644 --- a/internal/rpc/msg/send.go +++ b/internal/rpc/msg/send.go @@ -118,25 +118,14 @@ func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgDa conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAll} } else { // @Everyone and @other people conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAllAtMe} - - err = pbconv.SetConversationsCaller.Execute(ctx, &pbconv.SetConversationsReq{ - UserIDs: atUserID, - Conversation: conversation, - }) - if err != nil { + if err := m.conversationClient.SetConversations(ctx, atUserID, conversation); err != nil { log.ZWarn(ctx, "SetConversations", err, "userID", atUserID, "conversation", conversation) } - memberUserIDList = datautil.Single(atUserID, memberUserIDList) } conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAll} - - err = pbconv.SetConversationsCaller.Execute(ctx, &pbconv.SetConversationsReq{ - UserIDs: memberUserIDList, - Conversation: conversation, - }) - if err != nil { + if err := m.conversationClient.SetConversations(ctx, memberUserIDList, conversation); err != nil { log.ZWarn(ctx, "SetConversations", err, "userID", memberUserIDList, "conversation", conversation) } @@ -144,11 +133,7 @@ func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgDa } conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtMe} - err := pbconv.SetConversationsCaller.Execute(ctx, &pbconv.SetConversationsReq{ - UserIDs: msg.AtUserIDList, - Conversation: conversation, - }) - if err != nil { + if err := m.conversationClient.SetConversations(ctx, msg.AtUserIDList, conversation); err != nil { log.ZWarn(ctx, "SetConversations", err, msg.AtUserIDList, conversation) } } diff --git a/internal/rpc/msg/server.go b/internal/rpc/msg/server.go index 9bd2a69468..991fb87044 100644 --- a/internal/rpc/msg/server.go +++ b/internal/rpc/msg/server.go @@ -16,6 +16,7 @@ package msg import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis" @@ -26,8 +27,8 @@ import ( "github.com/openimsdk/tools/db/redisutil" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" + "github.com/openimsdk/open-im-server/v3/pkg/notification" "github.com/openimsdk/open-im-server/v3/pkg/rpccache" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/conversation" "github.com/openimsdk/protocol/msg" @@ -36,39 +37,39 @@ import ( ) type MessageInterceptorFunc func(ctx context.Context, globalConfig *Config, req *msg.SendMsgReq) (*sdkws.MsgData, error) -type ( - // MessageInterceptorChain defines a chain of message interceptor functions. - MessageInterceptorChain []MessageInterceptorFunc - // MsgServer encapsulates dependencies required for message handling. - msgServer struct { - RegisterCenter discovery.SvcDiscoveryRegistry // Service discovery registry for service registration. - MsgDatabase controller.CommonMsgDatabase // Interface for message database operations. - StreamMsgDatabase controller.StreamMsgDatabase - UserLocalCache *rpccache.UserLocalCache // Local cache for user data. - FriendLocalCache *rpccache.FriendLocalCache // Local cache for friend data. - GroupLocalCache *rpccache.GroupLocalCache // Local cache for group data. - ConversationLocalCache *rpccache.ConversationLocalCache // Local cache for conversation data. - Handlers MessageInterceptorChain // Chain of handlers for processing messages. - notificationSender *rpcclient.NotificationSender // RPC client for sending notifications. - msgNotificationSender *MsgNotificationSender // RPC client for sending msg notifications. - config *Config // Global configuration settings. - webhookClient *webhook.Client - msg.UnimplementedMsgServer - } +// MessageInterceptorChain defines a chain of message interceptor functions. +type MessageInterceptorChain []MessageInterceptorFunc - Config struct { - RpcConfig config.Msg - RedisConfig config.Redis - MongodbConfig config.Mongo - KafkaConfig config.Kafka - NotificationConfig config.Notification - Share config.Share - WebhooksConfig config.Webhooks - LocalCacheConfig config.LocalCache - Discovery config.Discovery - } -) +type Config struct { + RpcConfig config.Msg + RedisConfig config.Redis + MongodbConfig config.Mongo + KafkaConfig config.Kafka + NotificationConfig config.Notification + Share config.Share + WebhooksConfig config.Webhooks + LocalCacheConfig config.LocalCache + Discovery config.Discovery +} + +// MsgServer encapsulates dependencies required for message handling. +type msgServer struct { + msg.UnimplementedMsgServer + RegisterCenter discovery.SvcDiscoveryRegistry // Service discovery registry for service registration. + MsgDatabase controller.CommonMsgDatabase // Interface for message database operations. + StreamMsgDatabase controller.StreamMsgDatabase + UserLocalCache *rpccache.UserLocalCache // Local cache for user data. + FriendLocalCache *rpccache.FriendLocalCache // Local cache for friend data. + GroupLocalCache *rpccache.GroupLocalCache // Local cache for group data. + ConversationLocalCache *rpccache.ConversationLocalCache // Local cache for conversation data. + Handlers MessageInterceptorChain // Chain of handlers for processing messages. + notificationSender *rpcclient.NotificationSender // RPC client for sending notifications. + msgNotificationSender *MsgNotificationSender // RPC client for sending msg notifications. + config *Config // Global configuration settings. + webhookClient *webhook.Client + conversationClient *rpcli.ConversationClient +} func (m *msgServer) addInterceptorHandler(interceptorFunc ...MessageInterceptorFunc) { m.Handlers = append(m.Handlers, interceptorFunc...) @@ -107,16 +108,34 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg if err != nil { return err } + userConn, err := client.GetConn(ctx, config.Discovery.RpcService.User) + if err != nil { + return err + } + groupConn, err := client.GetConn(ctx, config.Discovery.RpcService.Group) + if err != nil { + return err + } + friendConn, err := client.GetConn(ctx, config.Discovery.RpcService.Friend) + if err != nil { + return err + } + conversationConn, err := client.GetConn(ctx, config.Discovery.RpcService.Conversation) + if err != nil { + return err + } + conversationClient := rpcli.NewConversationClient(conversationConn) s := &msgServer{ MsgDatabase: msgDatabase, StreamMsgDatabase: controller.NewStreamMsgDatabase(streamMsg), RegisterCenter: client, - UserLocalCache: rpccache.NewUserLocalCache(&config.LocalCacheConfig, rdb), - GroupLocalCache: rpccache.NewGroupLocalCache(&config.LocalCacheConfig, rdb), - ConversationLocalCache: rpccache.NewConversationLocalCache(&config.LocalCacheConfig, rdb), - FriendLocalCache: rpccache.NewFriendLocalCache(&config.LocalCacheConfig, rdb), + UserLocalCache: rpccache.NewUserLocalCache(rpcli.NewUserClient(userConn), &config.LocalCacheConfig, rdb), + GroupLocalCache: rpccache.NewGroupLocalCache(rpcli.NewGroupClient(groupConn), &config.LocalCacheConfig, rdb), + ConversationLocalCache: rpccache.NewConversationLocalCache(conversationClient, &config.LocalCacheConfig, rdb), + FriendLocalCache: rpccache.NewFriendLocalCache(rpcli.NewRelationClient(friendConn), &config.LocalCacheConfig, rdb), config: config, webhookClient: webhook.NewWebhookClient(config.WebhooksConfig.URL), + conversationClient: conversationClient, } s.notificationSender = rpcclient.NewNotificationSender(&config.NotificationConfig, rpcclient.WithLocalSendMsg(s.SendMsg)) diff --git a/internal/rpc/msg/stream_msg.go b/internal/rpc/msg/stream_msg.go index e216b10876..688d766c88 100644 --- a/internal/rpc/msg/stream_msg.go +++ b/internal/rpc/msg/stream_msg.go @@ -8,9 +8,7 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" "github.com/openimsdk/protocol/constant" - pbconv "github.com/openimsdk/protocol/conversation" "github.com/openimsdk/protocol/msg" - "github.com/openimsdk/protocol/rpccall" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/errs" ) @@ -74,10 +72,7 @@ func (m *msgServer) AppendStreamMsg(ctx context.Context, req *msg.AppendStreamMs if err := m.StreamMsgDatabase.AppendStreamMsg(ctx, req.ClientMsgID, int(req.StartIndex), req.Packets, req.End, deadlineTime); err != nil { return nil, err } - conversation, err := rpccall.ExtractField(ctx, pbconv.GetConversationCaller.Invoke, &pbconv.GetConversationReq{ - ConversationID: res.ConversationID, - OwnerUserID: res.UserID, - }, (*pbconv.GetConversationResp).GetConversation) + conversation, err := m.conversationClient.GetConversation(ctx, res.ConversationID, res.UserID) if err != nil { return nil, err } diff --git a/internal/rpc/relation/black.go b/internal/rpc/relation/black.go index 0fd9b87665..2108d7dc5a 100644 --- a/internal/rpc/relation/black.go +++ b/internal/rpc/relation/black.go @@ -21,7 +21,6 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/authverify" "github.com/openimsdk/open-im-server/v3/pkg/common/convert" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/protocol/relation" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/errs" @@ -39,7 +38,7 @@ func (s *friendServer) GetPaginationBlacks(ctx context.Context, req *relation.Ge return nil, err } resp = &relation.GetPaginationBlacksResp{} - resp.Blacks, err = convert.BlackDB2Pb(ctx, blacks, rpcclient.GetUsersInfoMap) + resp.Blacks, err = convert.BlackDB2Pb(ctx, blacks, s.userClient.GetUsersInfoMap) if err != nil { return nil, err } @@ -81,9 +80,7 @@ func (s *friendServer) AddBlack(ctx context.Context, req *relation.AddBlackReq) if err := s.webhookBeforeAddBlack(ctx, &s.config.WebhooksConfig.BeforeAddBlack, req); err != nil { return nil, err } - - _, err := rpcclient.GetUsersInfo(ctx, []string{req.OwnerUserID, req.BlackUserID}) - if err != nil { + if err := s.userClient.CheckUser(ctx, []string{req.OwnerUserID, req.BlackUserID}); err != nil { return nil, err } black := model.Black{ @@ -114,7 +111,7 @@ func (s *friendServer) GetSpecifiedBlacks(ctx context.Context, req *relation.Get return nil, errs.ErrArgs.WrapMsg("userIDList repeated") } - userMap, err := rpcclient.GetPublicUserInfoMap(ctx, req.UserIDList) + userMap, err := s.userClient.GetUsersInfoMap(ctx, req.UserIDList) if err != nil { return nil, err } @@ -132,13 +129,26 @@ func (s *friendServer) GetSpecifiedBlacks(ctx context.Context, req *relation.Get Blacks: make([]*sdkws.BlackInfo, 0, len(req.UserIDList)), } + toPublcUser := func(userID string) *sdkws.PublicUserInfo { + v, ok := userMap[userID] + if !ok { + return nil + } + return &sdkws.PublicUserInfo{ + UserID: v.UserID, + Nickname: v.Nickname, + FaceURL: v.FaceURL, + Ex: v.Ex, + } + } + for _, userID := range req.UserIDList { if black := blackMap[userID]; black != nil { resp.Blacks = append(resp.Blacks, &sdkws.BlackInfo{ OwnerUserID: black.OwnerUserID, CreateTime: black.CreateTime.UnixMilli(), - BlackUserInfo: userMap[userID], + BlackUserInfo: toPublcUser(userID), AddSource: black.AddSource, OperatorUserID: black.OperatorUserID, Ex: black.Ex, diff --git a/internal/rpc/relation/friend.go b/internal/rpc/relation/friend.go index b97a9d01f4..79db149705 100644 --- a/internal/rpc/relation/friend.go +++ b/internal/rpc/relation/friend.go @@ -16,6 +16,7 @@ package relation import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "github.com/openimsdk/tools/mq/memamq" @@ -31,7 +32,6 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/common/convert" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/relation" "github.com/openimsdk/protocol/sdkws" @@ -51,6 +51,7 @@ type friendServer struct { config *Config webhookClient *webhook.Client queue *memamq.MemoryQueue + userClient *rpcli.UserClient } type Config struct { @@ -90,10 +91,21 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg return err } + userConn, err := client.GetConn(ctx, config.Discovery.RpcService.User) + if err != nil { + return err + } + msgConn, err := client.GetConn(ctx, config.Discovery.RpcService.Msg) + if err != nil { + return err + } + userClient := rpcli.NewUserClient(userConn) + // Initialize notification sender notificationSender := NewFriendNotificationSender( &config.NotificationConfig, - WithRpcFunc(rpcclient.GetUsersInfo), + rpcli.NewMsgClient(msgConn), + WithRpcFunc(userClient.GetUsersInfo), ) localcache.InitLocalCache(&config.LocalCacheConfig) @@ -114,6 +126,7 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg config: config, webhookClient: webhook.NewWebhookClient(config.WebhooksConfig.URL), queue: memamq.NewMemoryQueue(16, 1024*1024), + userClient: userClient, }) return nil } @@ -130,7 +143,7 @@ func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *relation.Apply if err = s.webhookBeforeAddFriend(ctx, &s.config.WebhooksConfig.BeforeAddFriend, req); err != nil && err != servererrs.ErrCallbackContinue { return nil, err } - if _, err := rpcclient.GetUsersInfoMap(ctx, []string{req.ToUserID, req.FromUserID}); err != nil { + if err := s.userClient.CheckUser(ctx, []string{req.ToUserID, req.FromUserID}); err != nil { return nil, err } @@ -155,7 +168,7 @@ func (s *friendServer) ImportFriends(ctx context.Context, req *relation.ImportFr return nil, err } - if _, err := rpcclient.GetUsersInfo(ctx, append([]string{req.OwnerUserID}, req.FriendUserIDs...)); err != nil { + if err := s.userClient.CheckUser(ctx, append([]string{req.OwnerUserID}, req.FriendUserIDs...)); err != nil { return nil, err } if datautil.Contain(req.OwnerUserID, req.FriendUserIDs...) { @@ -296,7 +309,7 @@ func (s *friendServer) getFriend(ctx context.Context, ownerUserID string, friend if err != nil { return nil, err } - return convert.FriendsDB2Pb(ctx, friends, rpcclient.GetUsersInfoMap) + return convert.FriendsDB2Pb(ctx, friends, s.userClient.GetUsersInfoMap) } // Get the list of friend requests sent out proactively. @@ -308,7 +321,7 @@ func (s *friendServer) GetDesignatedFriendsApply(ctx context.Context, return nil, err } resp = &relation.GetDesignatedFriendsApplyResp{} - resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, rpcclient.GetUsersInfoMap) + resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, s.userClient.GetUsersInfoMap) if err != nil { return nil, err } @@ -327,7 +340,7 @@ func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *rel } resp = &relation.GetPaginationFriendsApplyToResp{} - resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, rpcclient.GetUsersInfoMap) + resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, s.userClient.GetUsersInfoMap) if err != nil { return nil, err } @@ -349,7 +362,7 @@ func (s *friendServer) GetPaginationFriendsApplyFrom(ctx context.Context, req *r return nil, err } - resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, rpcclient.GetUsersInfoMap) + resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, s.userClient.GetUsersInfoMap) if err != nil { return nil, err } @@ -380,7 +393,7 @@ func (s *friendServer) GetPaginationFriends(ctx context.Context, req *relation.G } resp = &relation.GetPaginationFriendsResp{} - resp.FriendsInfo, err = convert.FriendsDB2Pb(ctx, friends, rpcclient.GetUsersInfoMap) + resp.FriendsInfo, err = convert.FriendsDB2Pb(ctx, friends, s.userClient.GetUsersInfoMap) if err != nil { return nil, err } @@ -413,7 +426,7 @@ func (s *friendServer) GetSpecifiedFriendsInfo(ctx context.Context, req *relatio return nil, errs.ErrArgs.WrapMsg("userIDList repeated") } - userMap, err := rpcclient.GetUsersInfoMap(ctx, req.UserIDList) + userMap, err := s.userClient.GetUsersInfoMap(ctx, req.UserIDList) if err != nil { return nil, err } @@ -517,18 +530,3 @@ func (s *friendServer) UpdateFriends( s.notificationSender.FriendsInfoUpdateNotification(ctx, req.OwnerUserID, req.FriendUserIDs) return resp, nil } - -func (s *friendServer) GetIncrementalFriendsApplyTo(ctx context.Context, req *relation.GetIncrementalFriendsApplyToReq) (*relation.GetIncrementalFriendsApplyToResp, error) { - // TODO implement me - return nil, nil -} - -func (s *friendServer) GetIncrementalFriendsApplyFrom(ctx context.Context, req *relation.GetIncrementalFriendsApplyFromReq) (*relation.GetIncrementalFriendsApplyFromResp, error) { - // TODO implement me - return nil, nil -} - -func (s *friendServer) GetIncrementalBlacks(ctx context.Context, req *relation.GetIncrementalBlacksReq) (*relation.GetIncrementalBlacksResp, error) { - // TODO implement me - return nil, nil -} diff --git a/internal/rpc/relation/notification.go b/internal/rpc/relation/notification.go index ba43652005..a34a4d3227 100644 --- a/internal/rpc/relation/notification.go +++ b/internal/rpc/relation/notification.go @@ -16,6 +16,8 @@ package relation import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" + "github.com/openimsdk/protocol/msg" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/versionctx" @@ -25,8 +27,8 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/convert" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification" + "github.com/openimsdk/open-im-server/v3/pkg/notification" + "github.com/openimsdk/open-im-server/v3/pkg/notification/common_user" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/relation" "github.com/openimsdk/protocol/sdkws" @@ -36,7 +38,7 @@ import ( type FriendNotificationSender struct { *rpcclient.NotificationSender // Target not found err - getUsersInfo func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) + getUsersInfo func(ctx context.Context, userIDs []string) ([]common_user.CommonUser, error) // db controller db controller.FriendDatabase } @@ -53,7 +55,7 @@ func WithDBFunc( fn func(ctx context.Context, userIDs []string) (users []*relationtb.User, err error), ) friendNotificationSenderOptions { return func(s *FriendNotificationSender) { - f := func(ctx context.Context, userIDs []string) (result []notification.CommonUser, err error) { + f := func(ctx context.Context, userIDs []string) (result []common_user.CommonUser, err error) { users, err := fn(ctx, userIDs) if err != nil { return nil, err @@ -71,7 +73,7 @@ func WithRpcFunc( fn func(ctx context.Context, userIDs []string) ([]*sdkws.UserInfo, error), ) friendNotificationSenderOptions { return func(s *FriendNotificationSender) { - f := func(ctx context.Context, userIDs []string) (result []notification.CommonUser, err error) { + f := func(ctx context.Context, userIDs []string) (result []common_user.CommonUser, err error) { users, err := fn(ctx, userIDs) if err != nil { return nil, err @@ -85,12 +87,11 @@ func WithRpcFunc( } } -func NewFriendNotificationSender( - conf *config.Notification, - opts ...friendNotificationSenderOptions, -) *FriendNotificationSender { +func NewFriendNotificationSender(conf *config.Notification, msgClient *rpcli.MsgClient, opts ...friendNotificationSenderOptions) *FriendNotificationSender { f := &FriendNotificationSender{ - NotificationSender: rpcclient.NewNotificationSender(conf, rpcclient.WithRpcClient()), + NotificationSender: rpcclient.NewNotificationSender(conf, rpcclient.WithRpcClient(func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) { + return msgClient.SendMsg(ctx, req) + })), } for _, opt := range opts { opt(f) diff --git a/internal/rpc/third/log.go b/internal/rpc/third/log.go index 222cfad1dc..4d8cbc0bb3 100644 --- a/internal/rpc/third/log.go +++ b/internal/rpc/third/log.go @@ -19,11 +19,9 @@ import ( "crypto/rand" "time" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" - "github.com/openimsdk/open-im-server/v3/pkg/authverify" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/third" "github.com/openimsdk/tools/errs" @@ -150,7 +148,7 @@ func (t *thirdServer) SearchLogs(ctx context.Context, req *third.SearchLogsReq) for _, log := range logs { userIDs = append(userIDs, log.UserID) } - userMap, err := rpcclient.GetUsersInfoMap(ctx, userIDs) + userMap, err := t.userClient.GetUsersInfoMap(ctx, userIDs) if err != nil { return nil, err } diff --git a/internal/rpc/third/s3.go b/internal/rpc/third/s3.go index b4b064d7f4..8796fe824e 100644 --- a/internal/rpc/third/s3.go +++ b/internal/rpc/third/s3.go @@ -19,17 +19,14 @@ import ( "encoding/base64" "encoding/hex" "encoding/json" + "github.com/openimsdk/open-im-server/v3/pkg/authverify" "path" "strconv" "time" - "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "go.mongodb.org/mongo-driver/mongo" - "github.com/google/uuid" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" - "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/protocol/third" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" @@ -288,87 +285,35 @@ func (t *thirdServer) apiAddress(prefix, name string) string { } func (t *thirdServer) DeleteOutdatedData(ctx context.Context, req *third.DeleteOutdatedDataReq) (*third.DeleteOutdatedDataResp, error) { - var conf config.Third - expireTime := time.UnixMilli(req.ExpireTime) - - findPagination := &sdkws.RequestPagination{ - PageNumber: 1, - ShowNumber: 500, + if err := authverify.CheckAdmin(ctx, t.config.Share.IMAdminUserID); err != nil { + return nil, err } - + engine := t.config.RpcConfig.Object.Enable + expireTime := time.UnixMilli(req.ExpireTime) // Find all expired data in S3 database - total, models, err := t.s3dataBase.FindNeedDeleteObjectByDB(ctx, expireTime, req.ObjectGroup, findPagination) - if err != nil && errs.Unwrap(err) != mongo.ErrNoDocuments { - return nil, errs.Wrap(err) - } - - if total == 0 { - log.ZDebug(ctx, "Not have OutdatedData", "delete Total", total) - return &third.DeleteOutdatedDataResp{Count: int32(total)}, nil - } - - needDelObjectKeys := make([]string, len(models)) - for _, model := range models { - needDelObjectKeys = append(needDelObjectKeys, model.Key) + models, err := t.s3dataBase.FindExpirationObject(ctx, engine, expireTime, req.ObjectGroup, int64(req.Limit)) + if err != nil { + return nil, err } - - // Remove duplicate keys, have the same key use in different models - needDelObjectKeys = datautil.Distinct(needDelObjectKeys) - - for _, key := range needDelObjectKeys { - // Find all models by key - keyModels, err := t.s3dataBase.FindModelsByKey(ctx, key) - if err != nil && errs.Unwrap(err) != mongo.ErrNoDocuments { + for i, obj := range models { + if err := t.s3dataBase.DeleteSpecifiedData(ctx, engine, []string{obj.Name}); err != nil { return nil, errs.Wrap(err) } - - // check keyModels, if all keyModels. - needDelKey := true // Default can delete - for _, keymodel := range keyModels { - // If group is empty or CreateTime is after expireTime, can't delete this key - if keymodel.Group == "" || keymodel.CreateTime.After(expireTime) { - needDelKey = false - break - } - } - - // If this object is not referenced by not expire data, delete it - if needDelKey && t.minio != nil { - // If have a thumbnail, delete it - thumbnailKey, _ := t.getMinioImageThumbnailKey(ctx, key) - if thumbnailKey != "" { - err := t.s3dataBase.DeleteObject(ctx, thumbnailKey) - if err != nil { - log.ZWarn(ctx, "Delete thumbnail object is error:", errs.Wrap(err), "thumbnailKey", thumbnailKey) - } - } - - // Delete object - err = t.s3dataBase.DeleteObject(ctx, key) - if err != nil { - log.ZWarn(ctx, "Delete object is error", errs.Wrap(err), "object key", key) - } - - // Delete cache key - err = t.s3dataBase.DelS3Key(ctx, conf.Object.Enable, key) - if err != nil { - log.ZWarn(ctx, "Delete cache key is error:", errs.Wrap(err), "cache S3 key:", key) - } + if err := t.s3dataBase.DelS3Key(ctx, engine, obj.Name); err != nil { + return nil, err } - } - - // handle delete data in S3 database - for _, model := range models { - // Delete all expired data row in S3 database - err := t.s3dataBase.DeleteSpecifiedData(ctx, model.Engine, model.Name) + count, err := t.s3dataBase.GetKeyCount(ctx, engine, obj.Key) if err != nil { - return nil, errs.Wrap(err) + return nil, err + } + log.ZDebug(ctx, "delete s3 object record", "index", i, "s3", obj, "count", count) + if count == 0 { + if err := t.s3.DeleteObject(ctx, obj.Key); err != nil { + return nil, err + } } } - - log.ZDebug(ctx, "DeleteOutdatedData", "delete Total", total) - - return &third.DeleteOutdatedDataResp{Count: int32(total)}, nil + return &third.DeleteOutdatedDataResp{Count: int32(len(models))}, nil } type FormDataMate struct { diff --git a/internal/rpc/third/third.go b/internal/rpc/third/third.go index 77e6d459fa..0b8ca25a85 100644 --- a/internal/rpc/third/third.go +++ b/internal/rpc/third/third.go @@ -17,6 +17,7 @@ package third import ( "context" "fmt" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "time" "github.com/openimsdk/open-im-server/v3/pkg/common/config" @@ -44,7 +45,8 @@ type thirdServer struct { s3dataBase controller.S3Database defaultExpire time.Duration config *Config - minio *minio.Minio + s3 s3.Interface + userClient *rpcli.UserClient } type Config struct { @@ -79,13 +81,11 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg // Select the oss method according to the profile policy enable := config.RpcConfig.Object.Enable var ( - o s3.Interface - minioCli *minio.Minio + o s3.Interface ) switch enable { case "minio": - minioCli, err = minio.NewMinio(ctx, redis.NewMinioCache(rdb), *config.MinioConfig.Build()) - o = minioCli + o, err = minio.NewMinio(ctx, redis.NewMinioCache(rdb), *config.MinioConfig.Build()) case "cos": o, err = cos.NewCos(*config.RpcConfig.Object.Cos.Build()) case "oss": @@ -100,21 +100,22 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg if err != nil { return err } + userConn, err := client.GetConn(ctx, config.Discovery.RpcService.User) + if err != nil { + return err + } localcache.InitLocalCache(&config.LocalCacheConfig) third.RegisterThirdServer(server, &thirdServer{ thirdDatabase: controller.NewThirdDatabase(redis.NewThirdCache(rdb), logdb), s3dataBase: controller.NewS3Database(rdb, o, s3db), defaultExpire: time.Hour * 24 * 7, config: config, - minio: minioCli, + s3: o, + userClient: rpcli.NewUserClient(userConn), }) return nil } -func (t *thirdServer) getMinioImageThumbnailKey(ctx context.Context, name string) (string, error) { - return t.minio.GetImageThumbnailKey(ctx, name) -} - func (t *thirdServer) FcmUpdateToken(ctx context.Context, req *third.FcmUpdateTokenReq) (resp *third.FcmUpdateTokenResp, err error) { err = t.thirdDatabase.FcmUpdateToken(ctx, req.Account, int(req.PlatformID), req.FcmToken, req.ExpireTime) if err != nil { diff --git a/internal/rpc/user/notification.go b/internal/rpc/user/notification.go index 54e5b27d75..03fdf95bdb 100644 --- a/internal/rpc/user/notification.go +++ b/internal/rpc/user/notification.go @@ -16,19 +16,21 @@ package user import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" + "github.com/openimsdk/protocol/msg" relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification" + "github.com/openimsdk/open-im-server/v3/pkg/notification/common_user" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" + "github.com/openimsdk/open-im-server/v3/pkg/notification" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/sdkws" ) type UserNotificationSender struct { *rpcclient.NotificationSender - getUsersInfo func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) + getUsersInfo func(ctx context.Context, userIDs []string) ([]common_user.CommonUser, error) // db controller db controller.UserDatabase } @@ -45,7 +47,7 @@ func WithUserFunc( fn func(ctx context.Context, userIDs []string) (users []*relationtb.User, err error), ) userNotificationSenderOptions { return func(u *UserNotificationSender) { - f := func(ctx context.Context, userIDs []string) (result []notification.CommonUser, err error) { + f := func(ctx context.Context, userIDs []string) (result []common_user.CommonUser, err error) { users, err := fn(ctx, userIDs) if err != nil { return nil, err @@ -59,9 +61,11 @@ func WithUserFunc( } } -func NewUserNotificationSender(config *Config, opts ...userNotificationSenderOptions) *UserNotificationSender { +func NewUserNotificationSender(config *Config, msgClient *rpcli.MsgClient, opts ...userNotificationSenderOptions) *UserNotificationSender { f := &UserNotificationSender{ - NotificationSender: rpcclient.NewNotificationSender(&config.NotificationConfig, rpcclient.WithRpcClient()), + NotificationSender: rpcclient.NewNotificationSender(&config.NotificationConfig, rpcclient.WithRpcClient(func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) { + return msgClient.SendMsg(ctx, req) + })), } for _, opt := range opts { opt(f) diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go index c2bcabaa1d..c5ee3be706 100644 --- a/internal/rpc/user/user.go +++ b/internal/rpc/user/user.go @@ -17,6 +17,7 @@ package user import ( "context" "errors" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "math/rand" "strings" "sync" @@ -59,6 +60,8 @@ type userServer struct { RegisterCenter registry.SvcDiscoveryRegistry config *Config webhookClient *webhook.Client + groupClient *rpcli.GroupClient + relationClient *rpcli.RelationClient } type Config struct { @@ -91,6 +94,19 @@ func Start(ctx context.Context, config *Config, client registry.SvcDiscoveryRegi if err != nil { return err } + msgConn, err := client.GetConn(ctx, config.Discovery.RpcService.Msg) + if err != nil { + return err + } + groupConn, err := client.GetConn(ctx, config.Discovery.RpcService.Group) + if err != nil { + return err + } + friendConn, err := client.GetConn(ctx, config.Discovery.RpcService.Friend) + if err != nil { + return err + } + msgClient := rpcli.NewMsgClient(msgConn) userCache := redis.NewUserCacheRedis(rdb, &config.LocalCacheConfig, userDB, redis.GetRocksCacheOptions()) database := controller.NewUserDatabase(userDB, userCache, mgocli.GetTx()) localcache.InitLocalCache(&config.LocalCacheConfig) @@ -98,10 +114,13 @@ func Start(ctx context.Context, config *Config, client registry.SvcDiscoveryRegi online: redis.NewUserOnline(rdb), db: database, RegisterCenter: client, - friendNotificationSender: relation.NewFriendNotificationSender(&config.NotificationConfig, relation.WithDBFunc(database.FindWithError)), - userNotificationSender: NewUserNotificationSender(config, WithUserFunc(database.FindWithError)), + friendNotificationSender: relation.NewFriendNotificationSender(&config.NotificationConfig, msgClient, relation.WithDBFunc(database.FindWithError)), + userNotificationSender: NewUserNotificationSender(config, msgClient, WithUserFunc(database.FindWithError)), config: config, webhookClient: webhook.NewWebhookClient(config.WebhooksConfig.URL), + + groupClient: rpcli.NewGroupClient(groupConn), + relationClient: rpcli.NewRelationClient(friendConn), } pbuser.RegisterUserServer(server, u) return u.db.InitOnce(context.Background(), users) @@ -633,7 +652,7 @@ func (s *userServer) NotificationUserInfoUpdate(ctx context.Context, userID stri wg.Add(len(es)) go func() { defer wg.Done() - _, es[0] = group.NotificationUserInfoUpdateCaller.Invoke(ctx, &group.NotificationUserInfoUpdateReq{ + _, es[0] = s.groupClient.NotificationUserInfoUpdate(ctx, &group.NotificationUserInfoUpdateReq{ UserID: userID, OldUserInfo: oldUserInfo, NewUserInfo: newUserInfo, @@ -642,7 +661,7 @@ func (s *userServer) NotificationUserInfoUpdate(ctx context.Context, userID stri go func() { defer wg.Done() - _, es[1] = friendpb.NotificationUserInfoUpdateCaller.Invoke(ctx, &friendpb.NotificationUserInfoUpdateReq{ + _, es[1] = s.relationClient.NotificationUserInfoUpdate(ctx, &friendpb.NotificationUserInfoUpdateReq{ UserID: userID, OldUserInfo: oldUserInfo, NewUserInfo: newUserInfo, diff --git a/internal/tools/cron_task.go b/internal/tools/cron_task.go index c393efae97..71fd886f6e 100644 --- a/internal/tools/cron_task.go +++ b/internal/tools/cron_task.go @@ -2,10 +2,6 @@ package tools import ( "context" - "fmt" - "os" - "time" - "github.com/openimsdk/open-im-server/v3/pkg/common/config" kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discovery" pbconversation "github.com/openimsdk/protocol/conversation" @@ -60,87 +56,58 @@ func Start(ctx context.Context, config *CronTaskConfig) error { return err } - msgClient := msg.NewMsgClient(msgConn) - conversationClient := pbconversation.NewConversationClient(conversationConn) - thirdClient := third.NewThirdClient(thirdConn) - - crontab := cron.New() - - // scheduled hard delete outdated Msgs in specific time. - destructMsgsFunc := func() { - now := time.Now() - deltime := now.Add(-time.Hour * 24 * time.Duration(config.CronTask.RetainChatRecords)) - ctx := mcontext.SetOperationID(ctx, fmt.Sprintf("cron_%d_%d", os.Getpid(), deltime.UnixMilli())) - log.ZDebug(ctx, "Destruct chat records", "deltime", deltime, "timestamp", deltime.UnixMilli()) - - if _, err := msgClient.DestructMsgs(ctx, &msg.DestructMsgsReq{Timestamp: deltime.UnixMilli()}); err != nil { - log.ZError(ctx, "cron destruct chat records failed", err, "deltime", deltime, "cont", time.Since(now)) - return - } - log.ZDebug(ctx, "cron destruct chat records success", "deltime", deltime, "cont", time.Since(now)) - } - if _, err := crontab.AddFunc(config.CronTask.CronExecuteTime, destructMsgsFunc); err != nil { - return errs.Wrap(err) + srv := &cronServer{ + ctx: ctx, + config: config, + cron: cron.New(), + msgClient: msg.NewMsgClient(msgConn), + conversationClient: pbconversation.NewConversationClient(conversationConn), + thirdClient: third.NewThirdClient(thirdConn), } - // scheduled soft delete outdated Msgs in specific time when user set `is_msg_destruct` feature. - clearMsgFunc := func() { - now := time.Now() - ctx := mcontext.SetOperationID(ctx, fmt.Sprintf("cron_%d_%d", os.Getpid(), now.UnixMilli())) - log.ZDebug(ctx, "clear msg cron start", "now", now) - - conversations, err := conversationClient.GetConversationsNeedClearMsg(ctx, &pbconversation.GetConversationsNeedClearMsgReq{}) - if err != nil { - log.ZError(ctx, "Get conversation need Destruct msgs failed.", err) - return - } - - _, err = msgClient.ClearMsg(ctx, &msg.ClearMsgReq{Conversations: conversations.Conversations}) - if err != nil { - log.ZError(ctx, "Clear Msg failed.", err) - return - } - - log.ZDebug(ctx, "clear msg cron task completed", "cont", time.Since(now)) - } - if _, err := crontab.AddFunc(config.CronTask.CronExecuteTime, clearMsgFunc); err != nil { - return errs.Wrap(err) + if err := srv.registerClearS3(); err != nil { + return err } - - // scheduled delete outdated file Objects and their datas in specific time. - deleteObjectFunc := func() { - now := time.Now() - executeNum := 5 - // number of pagination. if need modify, need update value in third.DeleteOutdatedData - pageShowNumber := 500 - deleteTime := now.Add(-time.Hour * 24 * time.Duration(config.CronTask.FileExpireTime)) - ctx := mcontext.SetOperationID(ctx, fmt.Sprintf("cron_%d_%d", os.Getpid(), deleteTime.UnixMilli())) - log.ZDebug(ctx, "deleteoutDatedData", "deletetime", deleteTime, "timestamp", deleteTime.UnixMilli()) - - if len(config.CronTask.DeleteObjectType) == 0 { - log.ZDebug(ctx, "cron deleteoutDatedData not type need delete", "deletetime", deleteTime, "DeleteObjectType", config.CronTask.DeleteObjectType, "cont", time.Since(now)) - return - } - - for i := 0; i < executeNum; i++ { - resp, err := thirdClient.DeleteOutdatedData(ctx, &third.DeleteOutdatedDataReq{ExpireTime: deleteTime.UnixMilli(), ObjectGroup: config.CronTask.DeleteObjectType}) - if err != nil { - log.ZError(ctx, "cron deleteoutDatedData failed", err, "deleteTime", deleteTime, "cont", time.Since(now)) - return - } - if resp.Count == 0 || resp.Count < int32(pageShowNumber) { - break - } - } - - log.ZDebug(ctx, "cron deleteoutDatedData success", "deltime", deleteTime, "cont", time.Since(now)) + if err := srv.registerDeleteMsg(); err != nil { + return err } - if _, err := crontab.AddFunc(config.CronTask.CronExecuteTime, deleteObjectFunc); err != nil { - return errs.Wrap(err) + if err := srv.registerClearUserMsg(); err != nil { + return err } - log.ZDebug(ctx, "start cron task", "CronExecuteTime", config.CronTask.CronExecuteTime) - crontab.Start() + srv.cron.Start() <-ctx.Done() return nil } + +type cronServer struct { + ctx context.Context + config *CronTaskConfig + cron *cron.Cron + msgClient msg.MsgClient + conversationClient pbconversation.ConversationClient + thirdClient third.ThirdClient +} + +func (c *cronServer) registerClearS3() error { + if c.config.CronTask.FileExpireTime <= 0 || len(c.config.CronTask.DeleteObjectType) == 0 { + log.ZInfo(c.ctx, "disable scheduled cleanup of s3", "fileExpireTime", c.config.CronTask.FileExpireTime, "deleteObjectType", c.config.CronTask.DeleteObjectType) + return nil + } + _, err := c.cron.AddFunc(c.config.CronTask.CronExecuteTime, c.clearS3) + return errs.WrapMsg(err, "failed to register clear s3 cron task") +} + +func (c *cronServer) registerDeleteMsg() error { + if c.config.CronTask.RetainChatRecords <= 0 { + log.ZInfo(c.ctx, "disable scheduled cleanup of chat records", "retainChatRecords", c.config.CronTask.RetainChatRecords) + return nil + } + _, err := c.cron.AddFunc(c.config.CronTask.CronExecuteTime, c.deleteMsg) + return errs.WrapMsg(err, "failed to register delete msg cron task") +} + +func (c *cronServer) registerClearUserMsg() error { + _, err := c.cron.AddFunc(c.config.CronTask.CronExecuteTime, c.clearUserMsg) + return errs.WrapMsg(err, "failed to register clear user msg cron task") +} diff --git a/internal/tools/cron_test.go b/internal/tools/cron_test.go new file mode 100644 index 0000000000..8903490698 --- /dev/null +++ b/internal/tools/cron_test.go @@ -0,0 +1,63 @@ +package tools + +import ( + "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/config" + kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister" + pbconversation "github.com/openimsdk/protocol/conversation" + "github.com/openimsdk/protocol/msg" + "github.com/openimsdk/protocol/third" + "github.com/openimsdk/tools/mcontext" + "github.com/openimsdk/tools/mw" + "github.com/robfig/cron/v3" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "testing" +) + +func TestName(t *testing.T) { + conf := &config.Discovery{ + Enable: config.ETCD, + Etcd: config.Etcd{ + RootDirectory: "openim", + Address: []string{"localhost:12379"}, + }, + } + client, err := kdisc.NewDiscoveryRegister(conf, "source") + if err != nil { + panic(err) + } + client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials())) + ctx := mcontext.SetOpUserID(context.Background(), "imAdmin") + msgConn, err := client.GetConn(ctx, "msg-rpc-service") + if err != nil { + panic(err) + } + thirdConn, err := client.GetConn(ctx, "third-rpc-service") + if err != nil { + panic(err) + } + + conversationConn, err := client.GetConn(ctx, "conversation-rpc-service") + if err != nil { + panic(err) + } + + srv := &cronServer{ + ctx: ctx, + config: &CronTaskConfig{ + CronTask: config.CronTask{ + RetainChatRecords: 1, + FileExpireTime: 1, + DeleteObjectType: []string{"msg-picture", "msg-file", "msg-voice", "msg-video", "msg-video-snapshot", "sdklog", ""}, + }, + }, + cron: cron.New(), + msgClient: msg.NewMsgClient(msgConn), + conversationClient: pbconversation.NewConversationClient(conversationConn), + thirdClient: third.NewThirdClient(thirdConn), + } + srv.deleteMsg() + //srv.clearS3() + //srv.clearUserMsg() +} diff --git a/internal/tools/msg.go b/internal/tools/msg.go new file mode 100644 index 0000000000..cc00cc5b83 --- /dev/null +++ b/internal/tools/msg.go @@ -0,0 +1,36 @@ +package tools + +import ( + "fmt" + "github.com/openimsdk/protocol/msg" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/mcontext" + "os" + "time" +) + +func (c *cronServer) deleteMsg() { + now := time.Now() + deltime := now.Add(-time.Hour * 24 * time.Duration(c.config.CronTask.RetainChatRecords)) + operationID := fmt.Sprintf("cron_msg_%d_%d", os.Getpid(), deltime.UnixMilli()) + ctx := mcontext.SetOperationID(c.ctx, operationID) + log.ZDebug(ctx, "Destruct chat records", "deltime", deltime, "timestamp", deltime.UnixMilli()) + const ( + deleteCount = 10000 + deleteLimit = 50 + ) + var count int + for i := 1; i <= deleteCount; i++ { + ctx := mcontext.SetOperationID(c.ctx, fmt.Sprintf("%s_%d", operationID, i)) + resp, err := c.msgClient.DestructMsgs(ctx, &msg.DestructMsgsReq{Timestamp: deltime.UnixMilli(), Limit: deleteLimit}) + if err != nil { + log.ZError(ctx, "cron destruct chat records failed", err) + break + } + count += int(resp.Count) + if resp.Count < deleteLimit { + break + } + } + log.ZDebug(ctx, "cron destruct chat records end", "deltime", deltime, "cont", time.Since(now), "count", count) +} diff --git a/internal/tools/s3.go b/internal/tools/s3.go new file mode 100644 index 0000000000..9b6b9c4089 --- /dev/null +++ b/internal/tools/s3.go @@ -0,0 +1,79 @@ +package tools + +import ( + "fmt" + "github.com/openimsdk/protocol/third" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/mcontext" + "os" + "time" +) + +func (c *cronServer) clearS3() { + start := time.Now() + deleteTime := start.Add(-time.Hour * 24 * time.Duration(c.config.CronTask.FileExpireTime)) + operationID := fmt.Sprintf("cron_s3_%d_%d", os.Getpid(), deleteTime.UnixMilli()) + ctx := mcontext.SetOperationID(c.ctx, operationID) + log.ZDebug(ctx, "deleteoutDatedData", "deletetime", deleteTime, "timestamp", deleteTime.UnixMilli()) + const ( + deleteCount = 10000 + deleteLimit = 100 + ) + + var count int + for i := 1; i <= deleteCount; i++ { + resp, err := c.thirdClient.DeleteOutdatedData(ctx, &third.DeleteOutdatedDataReq{ExpireTime: deleteTime.UnixMilli(), ObjectGroup: c.config.CronTask.DeleteObjectType, Limit: deleteLimit}) + if err != nil { + log.ZError(ctx, "cron deleteoutDatedData failed", err) + return + } + count += int(resp.Count) + if resp.Count < deleteLimit { + break + } + } + log.ZDebug(ctx, "cron deleteoutDatedData success", "deltime", deleteTime, "cont", time.Since(start), "count", count) +} + +// var req *third.DeleteOutdatedDataReq +// count1, err := ExtractField(ctx, c.thirdClient.DeleteOutdatedData, req, (*third.DeleteOutdatedDataResp).GetCount) +// +// c.thirdClient.DeleteOutdatedData(ctx, &third.DeleteOutdatedDataReq{}) +// msggateway.GetUsersOnlineStatusCaller.Invoke(ctx, &msggateway.GetUsersOnlineStatusReq{}) +// +// var cli ThirdClient +// +// c111, err := cli.DeleteOutdatedData(ctx, 100) +// +// cli.ThirdClient.DeleteOutdatedData(ctx, &third.DeleteOutdatedDataReq{}) +// +// cli.AuthSign(ctx, &third.AuthSignReq{}) +// +// cli.SetAppBadge() +// +//} +// +//func extractField[A, B, C any](ctx context.Context, fn func(ctx context.Context, req *A, opts ...grpc.CallOption) (*B, error), req *A, get func(*B) C) (C, error) { +// resp, err := fn(ctx, req) +// if err != nil { +// var c C +// return c, err +// } +// return get(resp), nil +//} +// +//func ignore(_ any, err error) error { +// return err +//} +// +//type ThirdClient struct { +// third.ThirdClient +//} +// +//func (c *ThirdClient) DeleteOutdatedData(ctx context.Context, expireTime int64) (int32, error) { +// return extractField(ctx, c.ThirdClient.DeleteOutdatedData, &third.DeleteOutdatedDataReq{ExpireTime: expireTime}, (*third.DeleteOutdatedDataResp).GetCount) +//} +// +//func (c *ThirdClient) DeleteOutdatedData1(ctx context.Context, expireTime int64) error { +// return ignore(c.ThirdClient.DeleteOutdatedData(ctx, &third.DeleteOutdatedDataReq{ExpireTime: expireTime})) +//} diff --git a/internal/tools/user_msg.go b/internal/tools/user_msg.go new file mode 100644 index 0000000000..a4afa769ed --- /dev/null +++ b/internal/tools/user_msg.go @@ -0,0 +1,34 @@ +package tools + +import ( + "fmt" + pbconversation "github.com/openimsdk/protocol/conversation" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/mcontext" + "os" + "time" +) + +func (c *cronServer) clearUserMsg() { + now := time.Now() + operationID := fmt.Sprintf("cron_user_msg_%d_%d", os.Getpid(), now.UnixMilli()) + ctx := mcontext.SetOperationID(c.ctx, operationID) + log.ZDebug(ctx, "clear user msg cron start") + const ( + deleteCount = 10000 + deleteLimit = 100 + ) + var count int + for i := 1; i <= deleteCount; i++ { + resp, err := c.conversationClient.ClearUserConversationMsg(ctx, &pbconversation.ClearUserConversationMsgReq{Timestamp: now.UnixMilli(), Limit: deleteLimit}) + if err != nil { + log.ZError(ctx, "ClearUserConversationMsg failed.", err) + return + } + count += int(resp.Count) + if resp.Count < deleteLimit { + break + } + } + log.ZDebug(ctx, "clear user msg cron task completed", "cont", time.Since(now), "count", count) +} diff --git a/pkg/common/convert/group.go b/pkg/common/convert/group.go index bc2b2f9985..5e41599c60 100644 --- a/pkg/common/convert/group.go +++ b/pkg/common/convert/group.go @@ -80,9 +80,18 @@ func Db2PbGroupMember(m *model.GroupMember) *sdkws.GroupMemberFullInfo { } } -func Db2PbGroupRequest(m *model.GroupRequest, user *sdkws.PublicUserInfo, group *sdkws.GroupInfo) *sdkws.GroupRequest { +func Db2PbGroupRequest(m *model.GroupRequest, user *sdkws.UserInfo, group *sdkws.GroupInfo) *sdkws.GroupRequest { + var pu *sdkws.PublicUserInfo + if user != nil { + pu = &sdkws.PublicUserInfo{ + UserID: user.UserID, + Nickname: user.Nickname, + FaceURL: user.FaceURL, + Ex: user.Ex, + } + } return &sdkws.GroupRequest{ - UserInfo: user, + UserInfo: pu, GroupInfo: group, HandleResult: m.HandleResult, ReqMsg: m.ReqMsg, diff --git a/pkg/common/startrpc/start.go b/pkg/common/startrpc/start.go index e6637365bb..d610e8e5a4 100644 --- a/pkg/common/startrpc/start.go +++ b/pkg/common/startrpc/start.go @@ -28,7 +28,6 @@ import ( conf "github.com/openimsdk/open-im-server/v3/pkg/common/config" disetcd "github.com/openimsdk/open-im-server/v3/pkg/common/discovery/etcd" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/tools/discovery/etcd" "github.com/openimsdk/tools/utils/datautil" "github.com/openimsdk/tools/utils/jsonutil" @@ -103,10 +102,6 @@ func Start[T any](ctx context.Context, discovery *conf.Discovery, prometheusConf defer client.Close() client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin"))) - if err = rpcclient.InitRpcCaller(client, discovery.RpcService); err != nil { - return err - } - // var reg *prometheus.Registry // var metric *grpcprometheus.ServerMetrics if prometheusConfig.Enable { diff --git a/pkg/common/storage/controller/conversation.go b/pkg/common/storage/controller/conversation.go index bf41cce957..d4088e0c0e 100644 --- a/pkg/common/storage/controller/conversation.go +++ b/pkg/common/storage/controller/conversation.go @@ -74,6 +74,8 @@ type ConversationDatabase interface { GetNotNotifyConversationIDs(ctx context.Context, userID string) ([]string, error) // GetPinnedConversationIDs gets pinned conversationIDs by userID GetPinnedConversationIDs(ctx context.Context, userID string) ([]string, error) + // FindRandConversation finds random conversations based on the specified timestamp and limit. + FindRandConversation(ctx context.Context, ts int64, limit int) ([]*relationtb.Conversation, error) } func NewConversationDatabase(conversation database.Conversation, cache cache.ConversationCache, tx tx.Tx) ConversationDatabase { @@ -401,3 +403,7 @@ func (c *conversationDatabase) GetPinnedConversationIDs(ctx context.Context, use } return conversationIDs, nil } + +func (c *conversationDatabase) FindRandConversation(ctx context.Context, ts int64, limit int) ([]*relationtb.Conversation, error) { + return c.conversationDB.FindRandConversation(ctx, ts, limit) +} diff --git a/pkg/common/storage/controller/msg.go b/pkg/common/storage/controller/msg.go index 3c3cd9671b..c29544c333 100644 --- a/pkg/common/storage/controller/msg.go +++ b/pkg/common/storage/controller/msg.go @@ -18,7 +18,6 @@ import ( "context" "encoding/json" "errors" - "strings" "time" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" @@ -69,6 +68,7 @@ type CommonMsgDatabase interface { GetMaxSeqs(ctx context.Context, conversationIDs []string) (map[string]int64, error) GetMaxSeq(ctx context.Context, conversationID string) (int64, error) SetMinSeqs(ctx context.Context, seqs map[string]int64) error + SetMinSeq(ctx context.Context, conversationID string, seq int64) error SetUserConversationsMinSeqs(ctx context.Context, userID string, seqs map[string]int64) (err error) SetHasReadSeq(ctx context.Context, userID string, conversationID string, hasReadSeq int64) error @@ -95,13 +95,16 @@ type CommonMsgDatabase interface { ConvertMsgsDocLen(ctx context.Context, conversationIDs []string) // get Msg when destruct msg before - GetBeforeMsg(ctx context.Context, ts int64, docIds []string, limit int) ([]*model.MsgDocModel, error) - DeleteDocMsgBefore(ctx context.Context, ts int64, doc *model.MsgDocModel) ([]int, error) + //DeleteDocMsgBefore(ctx context.Context, ts int64, doc *model.MsgDocModel) ([]int, error) - GetDocIDs(ctx context.Context) ([]string, error) + GetRandBeforeMsg(ctx context.Context, ts int64, limit int) ([]*model.MsgDocModel, error) SetUserConversationsMaxSeq(ctx context.Context, conversationID string, userID string, seq int64) error SetUserConversationsMinSeq(ctx context.Context, conversationID string, userID string, seq int64) error + + DeleteDoc(ctx context.Context, docID string) error + + GetLastMessageSeqByTime(ctx context.Context, conversationID string, time int64) (int64, error) } func NewCommonMsgDatabase(msgDocModel database.Msg, msg cache.MsgCache, seqUser cache.SeqUser, seqConversation cache.SeqConversationCache, kafkaConf *config.Kafka) (CommonMsgDatabase, error) { @@ -806,9 +809,10 @@ func (db *commonMsgDatabase) GetMaxSeq(ctx context.Context, conversationID strin return db.seqConversation.GetMaxSeq(ctx, conversationID) } -func (db *commonMsgDatabase) SetMinSeq(ctx context.Context, conversationID string, minSeq int64) error { - return db.seqConversation.SetMinSeq(ctx, conversationID, minSeq) -} +// +//func (db *commonMsgDatabase) SetMinSeq(ctx context.Context, conversationID string, minSeq int64) error { +// return db.seqConversation.SetMinSeq(ctx, conversationID, minSeq) +//} func (db *commonMsgDatabase) SetMinSeqs(ctx context.Context, seqs map[string]int64) error { return db.seqConversation.SetMinSeqs(ctx, seqs) @@ -947,56 +951,40 @@ func (db *commonMsgDatabase) ConvertMsgsDocLen(ctx context.Context, conversation db.msgDocDatabase.ConvertMsgsDocLen(ctx, conversationIDs) } -func (db *commonMsgDatabase) GetBeforeMsg(ctx context.Context, ts int64, docIDs []string, limit int) ([]*model.MsgDocModel, error) { - var msgs []*model.MsgDocModel - for i := 0; i < len(docIDs); i += 1000 { - end := i + 1000 - if end > len(docIDs) { - end = len(docIDs) - } - - res, err := db.msgDocDatabase.GetBeforeMsg(ctx, ts, docIDs[i:end], limit) - if err != nil { - return nil, err - } - msgs = append(msgs, res...) - - if len(msgs) >= limit { - return msgs[:limit], nil - } - } - return msgs, nil +func (db *commonMsgDatabase) GetRandBeforeMsg(ctx context.Context, ts int64, limit int) ([]*model.MsgDocModel, error) { + return db.msgDocDatabase.GetRandBeforeMsg(ctx, ts, limit) } -func (db *commonMsgDatabase) DeleteDocMsgBefore(ctx context.Context, ts int64, doc *model.MsgDocModel) ([]int, error) { - var notNull int - index := make([]int, 0, len(doc.Msg)) - for i, message := range doc.Msg { - if message.Msg != nil { - notNull++ - if message.Msg.SendTime < ts { - index = append(index, i) - } - } - } - if len(index) == 0 { - return index, nil - } - maxSeq := doc.Msg[index[len(index)-1]].Msg.Seq - conversationID := doc.DocID[:strings.LastIndex(doc.DocID, ":")] - if err := db.setMinSeq(ctx, conversationID, maxSeq+1); err != nil { - return index, err - } - if len(index) == notNull { - log.ZDebug(ctx, "Delete db in Doc", "DocID", doc.DocID, "index", index, "maxSeq", maxSeq) - return index, db.msgDocDatabase.DeleteDoc(ctx, doc.DocID) - } else { - log.ZDebug(ctx, "delete db in index", "DocID", doc.DocID, "index", index, "maxSeq", maxSeq) - return index, db.msgDocDatabase.DeleteMsgByIndex(ctx, doc.DocID, index) - } -} - -func (db *commonMsgDatabase) setMinSeq(ctx context.Context, conversationID string, seq int64) error { +// +//func (db *commonMsgDatabase) DeleteDocMsgBefore(ctx context.Context, ts int64, doc *model.MsgDocModel) ([]int, error) { +// var notNull int +// index := make([]int, 0, len(doc.Msg)) +// for i, message := range doc.Msg { +// if message.Msg != nil { +// notNull++ +// if message.Msg.SendTime < ts { +// index = append(index, i) +// } +// } +// } +// if len(index) == 0 { +// return index, nil +// } +// maxSeq := doc.Msg[index[len(index)-1]].Msg.Seq +// conversationID := doc.DocID[:strings.LastIndex(doc.DocID, ":")] +// if err := db.SetMinSeq(ctx, conversationID, maxSeq+1); err != nil { +// return index, err +// } +// if len(index) == notNull { +// log.ZDebug(ctx, "Delete db in Doc", "DocID", doc.DocID, "index", index, "maxSeq", maxSeq) +// return index, db.msgDocDatabase.DeleteDoc(ctx, doc.DocID) +// } else { +// log.ZDebug(ctx, "delete db in index", "DocID", doc.DocID, "index", index, "maxSeq", maxSeq) +// return index, db.msgDocDatabase.DeleteMsgByIndex(ctx, doc.DocID, index) +// } +//} + +func (db *commonMsgDatabase) SetMinSeq(ctx context.Context, conversationID string, seq int64) error { dbSeq, err := db.seqConversation.GetMinSeq(ctx, conversationID) if err != nil { if errors.Is(errs.Unwrap(err), redis.Nil) { @@ -1010,8 +998,8 @@ func (db *commonMsgDatabase) setMinSeq(ctx context.Context, conversationID strin return db.seqConversation.SetMinSeq(ctx, conversationID, seq) } -func (db *commonMsgDatabase) GetDocIDs(ctx context.Context) ([]string, error) { - return db.msgDocDatabase.GetDocIDs(ctx) +func (db *commonMsgDatabase) GetRandDocIDs(ctx context.Context, limit int) ([]string, error) { + return db.msgDocDatabase.GetRandDocIDs(ctx, limit) } func (db *commonMsgDatabase) GetCacheMaxSeqWithTime(ctx context.Context, conversationIDs []string) (map[string]database.SeqTime, error) { @@ -1026,3 +1014,11 @@ func (db *commonMsgDatabase) GetMaxSeqsWithTime(ctx context.Context, conversatio // todo: only the time in the redis cache will be taken, not the message time return db.seqConversation.GetMaxSeqsWithTime(ctx, conversationIDs) } + +func (db *commonMsgDatabase) DeleteDoc(ctx context.Context, docID string) error { + return db.msgDocDatabase.DeleteDoc(ctx, docID) +} + +func (db *commonMsgDatabase) GetLastMessageSeqByTime(ctx context.Context, conversationID string, time int64) (int64, error) { + return db.msgDocDatabase.GetLastMessageSeqByTime(ctx, conversationID, time) +} diff --git a/pkg/common/storage/controller/s3.go b/pkg/common/storage/controller/s3.go index 4e5ad18b6e..6693d2ddea 100644 --- a/pkg/common/storage/controller/s3.go +++ b/pkg/common/storage/controller/s3.go @@ -24,7 +24,6 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" - "github.com/openimsdk/tools/db/pagination" "github.com/openimsdk/tools/s3" "github.com/openimsdk/tools/s3/cont" "github.com/redis/go-redis/v9" @@ -40,11 +39,10 @@ type S3Database interface { SetObject(ctx context.Context, info *model.Object) error StatObject(ctx context.Context, name string) (*s3.ObjectInfo, error) FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*s3.FormData, error) - FindNeedDeleteObjectByDB(ctx context.Context, duration time.Time, needDelType []string, pagination pagination.Pagination) (total int64, objects []*model.Object, err error) - DeleteObject(ctx context.Context, name string) error - DeleteSpecifiedData(ctx context.Context, engine string, name string) error - FindModelsByKey(ctx context.Context, key string) (objects []*model.Object, err error) + FindExpirationObject(ctx context.Context, engine string, expiration time.Time, needDelType []string, count int64) ([]*model.Object, error) + DeleteSpecifiedData(ctx context.Context, engine string, name []string) error DelS3Key(ctx context.Context, engine string, keys ...string) error + GetKeyCount(ctx context.Context, engine string, key string) (int64, error) } func NewS3Database(rdb redis.UniversalClient, s3 s3.Interface, obj database.ObjectInfo) S3Database { @@ -120,19 +118,17 @@ func (s *s3Database) StatObject(ctx context.Context, name string) (*s3.ObjectInf func (s *s3Database) FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*s3.FormData, error) { return s.s3.FormData(ctx, name, size, contentType, duration) } -func (s *s3Database) FindNeedDeleteObjectByDB(ctx context.Context, duration time.Time, needDelType []string, pagination pagination.Pagination) (total int64, objects []*model.Object, err error) { - return s.db.FindNeedDeleteObjectByDB(ctx, duration, needDelType, pagination) -} -func (s *s3Database) DeleteObject(ctx context.Context, name string) error { - return s.s3.DeleteObject(ctx, name) +func (s *s3Database) FindExpirationObject(ctx context.Context, engine string, expiration time.Time, needDelType []string, count int64) ([]*model.Object, error) { + return s.db.FindExpirationObject(ctx, engine, expiration, needDelType, count) } -func (s *s3Database) DeleteSpecifiedData(ctx context.Context, engine string, name string) error { - return s.db.Delete(ctx, engine, name) + +func (s *s3Database) GetKeyCount(ctx context.Context, engine string, key string) (int64, error) { + return s.db.GetKeyCount(ctx, engine, key) } -func (s *s3Database) FindModelsByKey(ctx context.Context, key string) (objects []*model.Object, err error) { - return s.db.FindModelsByKey(ctx, key) +func (s *s3Database) DeleteSpecifiedData(ctx context.Context, engine string, name []string) error { + return s.db.Delete(ctx, engine, name) } func (s *s3Database) DelS3Key(ctx context.Context, engine string, keys ...string) error { diff --git a/pkg/common/storage/database/conversation.go b/pkg/common/storage/database/conversation.go index 30ca01ee71..1fb53cfed2 100644 --- a/pkg/common/storage/database/conversation.go +++ b/pkg/common/storage/database/conversation.go @@ -42,4 +42,5 @@ type Conversation interface { GetConversationIDsNeedDestruct(ctx context.Context) ([]*model.Conversation, error) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) FindConversationUserVersion(ctx context.Context, userID string, version uint, limit int) (*model.VersionLog, error) + FindRandConversation(ctx context.Context, ts int64, limit int) ([]*model.Conversation, error) } diff --git a/pkg/common/storage/database/mgo/conversation.go b/pkg/common/storage/database/mgo/conversation.go index 10e223c893..851ec99c40 100644 --- a/pkg/common/storage/database/mgo/conversation.go +++ b/pkg/common/storage/database/mgo/conversation.go @@ -228,3 +228,35 @@ func (c *ConversationMgo) GetConversationNotReceiveMessageUserIDs(ctx context.Co func (c *ConversationMgo) FindConversationUserVersion(ctx context.Context, userID string, version uint, limit int) (*model.VersionLog, error) { return c.version.FindChangeLog(ctx, userID, version, limit) } + +func (c *ConversationMgo) FindRandConversation(ctx context.Context, ts int64, limit int) ([]*model.Conversation, error) { + pipeline := []bson.M{ + { + "$match": bson.M{ + "is_msg_destruct": true, + "msg_destruct_time": bson.M{"$ne": 0}, + }, + }, + { + "$addFields": bson.M{ + "next_msg_destruct_timestamp": bson.M{ + "$add": []any{ + bson.M{ + "$toLong": "$latest_msg_destruct_time", + }, "$msg_destruct_time"}, + }, + }, + }, + { + "$match": bson.M{ + "next_msg_destruct_timestamp": bson.M{"$lt": ts}, + }, + }, + { + "$sample": bson.M{ + "size": limit, + }, + }, + } + return mongoutil.Aggregate[*model.Conversation](ctx, c.coll, pipeline) +} diff --git a/pkg/common/storage/database/mgo/msg.go b/pkg/common/storage/database/mgo/msg.go index fc1fe47eab..f371766958 100644 --- a/pkg/common/storage/database/mgo/msg.go +++ b/pkg/common/storage/database/mgo/msg.go @@ -1227,8 +1227,7 @@ func (m *MsgMgo) ConvertMsgsDocLen(ctx context.Context, conversationIDs []string } } -func (m *MsgMgo) GetDocIDs(ctx context.Context) ([]string, error) { - limit := 5000 +func (m *MsgMgo) GetRandDocIDs(ctx context.Context, limit int) ([]string, error) { var skip int var docIDs []string var offset int @@ -1267,15 +1266,18 @@ func (m *MsgMgo) GetDocIDs(ctx context.Context) ([]string, error) { return docIDs, errs.Wrap(err) } -func (m *MsgMgo) GetBeforeMsg(ctx context.Context, ts int64, docIDs []string, limit int) ([]*model.MsgDocModel, error) { +func (m *MsgMgo) GetRandBeforeMsg(ctx context.Context, ts int64, limit int) ([]*model.MsgDocModel, error) { return mongoutil.Aggregate[*model.MsgDocModel](ctx, m.coll, []bson.M{ { "$match": bson.M{ - "doc_id": bson.M{ - "$in": docIDs, - }, - "msgs.msg.send_time": bson.M{ - "$lt": ts, + "msgs": bson.M{ + "$not": bson.M{ + "$elemMatch": bson.M{ + "msg.send_time": bson.M{ + "$gt": ts, + }, + }, + }, }, }, }, @@ -1288,7 +1290,9 @@ func (m *MsgMgo) GetBeforeMsg(ctx context.Context, ts int64, docIDs []string, li }, }, { - "$limit": limit, + "$sample": bson.M{ + "size": limit, + }, }, }) } @@ -1305,53 +1309,58 @@ func (m *MsgMgo) DeleteMsgByIndex(ctx context.Context, docID string, index []int return mongoutil.UpdateOne(ctx, m.coll, bson.M{"doc_id": docID}, bson.M{"$set": set}, true) } -//func (m *MsgMgo) ClearMsg(ctx context.Context, t time.Time) (int64, error) { -// ts := t.UnixMilli() -// var count int64 -// for { -// msgs, err := m.GetBeforeMsg(ctx, ts, 100) -// if err != nil { -// return count, err -// } -// if len(msgs) == 0 { -// return count, nil -// } -// for _, msg := range msgs { -// num, err := m.deleteOneMsg(ctx, ts, msg) -// count += num -// if err != nil { -// return count, err -// } -// } -// } -//} - func (m *MsgMgo) DeleteDoc(ctx context.Context, docID string) error { return mongoutil.DeleteOne(ctx, m.coll, bson.M{"doc_id": docID}) } -//func (m *MsgMgo) DeleteDocMsg(ctx context.Context, ts int64, doc *relation.MsgDocModel) (int64, error) { -// var notNull int -// index := make([]int, 0, len(doc.Msg)) -// for i, message := range doc.Msg { -// if message.Msg != nil { -// notNull++ -// if message.Msg.SendTime < ts { -// index = append(index, i) -// } -// } -// } -// if len(index) == 0 { -// return 0, errs.New("no msg to delete").WrapMsg("deleteOneMsg", "docID", doc.DocID) -// } -// if len(index) == notNull { -// if err := m.DeleteDoc(ctx, doc.DocID); err != nil { -// return 0, err -// } -// } else { -// if err := m.setNullMsg(ctx, doc.DocID, index); err != nil { -// return 0, err -// } -// } -// return int64(len(index)), nil -//} +func (m *MsgMgo) GetLastMessageSeqByTime(ctx context.Context, conversationID string, time int64) (int64, error) { + pipeline := []bson.M{ + { + "$match": bson.M{ + "doc_id": bson.M{ + "$regex": fmt.Sprintf("^%s", conversationID), + }, + }, + }, + { + "$match": bson.M{ + "msgs.msg.send_time": bson.M{ + "$lte": time, + }, + }, + }, + { + "$sort": bson.M{ + "_id": -1, + }, + }, + { + "$limit": 1, + }, + { + "$project": bson.M{ + "_id": 0, + "doc_id": 1, + "msgs.msg.send_time": 1, + "msgs.msg.seq": 1, + }, + }, + } + res, err := mongoutil.Aggregate[*model.MsgDocModel](ctx, m.coll, pipeline) + if err != nil { + return 0, err + } + if len(res) == 0 { + return 0, nil + } + var seq int64 + for _, v := range res[0].Msg { + if v.Msg == nil { + continue + } + if v.Msg.SendTime <= time { + seq = v.Msg.Seq + } + } + return seq, nil +} diff --git a/pkg/common/storage/database/mgo/msg_test.go b/pkg/common/storage/database/mgo/msg_test.go index 5aed4dc511..992090552e 100644 --- a/pkg/common/storage/database/mgo/msg_test.go +++ b/pkg/common/storage/database/mgo/msg_test.go @@ -3,12 +3,11 @@ package mgo import ( "context" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "github.com/openimsdk/protocol/msg" - "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/db/mongoutil" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" + "math" "math/rand" "strconv" "testing" @@ -16,35 +15,45 @@ import ( ) func TestName1(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*300) - defer cancel() - cli := Result(mongo.Connect(ctx, options.Client().ApplyURI("mongodb://openIM:openIM123@172.16.8.48:37017/openim_v3?maxPoolSize=100").SetConnectTimeout(5*time.Second))) - - v := &MsgMgo{ - coll: cli.Database("openim_v3").Collection("msg3"), - } - - req := &msg.SearchMessageReq{ - //RecvID: "3187706596", - //SendID: "7009965934", - ContentType: 101, - //SendTime: "2024-05-06", - //SessionType: 3, - Pagination: &sdkws.RequestPagination{ - PageNumber: 1, - ShowNumber: 10, - }, - } - total, res, err := v.SearchMessage(ctx, req) - if err != nil { - panic(err) - } - - for i, re := range res { - t.Logf("%d => %d | %+v", i+1, re.Msg.Seq, re.Msg.Content) - } - - t.Log(total) + //ctx, cancel := context.WithTimeout(context.Background(), time.Second*300) + //defer cancel() + //cli := Result(mongo.Connect(ctx, options.Client().ApplyURI("mongodb://openIM:openIM123@172.16.8.66:37017/openim_v3?maxPoolSize=100").SetConnectTimeout(5*time.Second))) + // + //v := &MsgMgo{ + // coll: cli.Database("openim_v3").Collection("msg3"), + //} + // + //req := &msg.SearchMessageReq{ + // //RecvID: "3187706596", + // //SendID: "7009965934", + // ContentType: 101, + // //SendTime: "2024-05-06", + // //SessionType: 3, + // Pagination: &sdkws.RequestPagination{ + // PageNumber: 1, + // ShowNumber: 10, + // }, + //} + //total, res, err := v.SearchMessage(ctx, req) + //if err != nil { + // panic(err) + //} + // + //for i, re := range res { + // t.Logf("%d => %d | %+v", i+1, re.Msg.Seq, re.Msg.Content) + //} + // + //t.Log(total) + // + //msg, err := NewMsgMongo(cli.Database("openim_v3")) + //if err != nil { + // panic(err) + //} + //res, err := msg.GetBeforeMsg(ctx, time.Now().UnixMilli(), []string{"1:0"}, 1000) + //if err != nil { + // panic(err) + //} + //t.Log(len(res)) } func TestName10(t *testing.T) { @@ -73,3 +82,33 @@ func TestName10(t *testing.T) { } } + +func TestName3(t *testing.T) { + t.Log(uint64(math.MaxUint64)) + t.Log(int64(math.MaxInt64)) + + t.Log(int64(math.MinInt64)) +} + +func TestName4(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*300) + defer cancel() + cli := Result(mongo.Connect(ctx, options.Client().ApplyURI("mongodb://openIM:openIM123@172.16.8.66:37017/openim_v3?maxPoolSize=100").SetConnectTimeout(5*time.Second))) + + msg, err := NewMsgMongo(cli.Database("openim_v3")) + if err != nil { + panic(err) + } + ts := time.Now().Add(-time.Hour * 24 * 5).UnixMilli() + t.Log(ts) + res, err := msg.GetLastMessageSeqByTime(ctx, "sg_1523453548", ts) + if err != nil { + panic(err) + } + t.Log(res) +} + +func TestName5(t *testing.T) { + var v time.Time + t.Log(v.UnixMilli()) +} diff --git a/pkg/common/storage/database/mgo/object.go b/pkg/common/storage/database/mgo/object.go index 5bc329d33b..624eb84a0d 100644 --- a/pkg/common/storage/database/mgo/object.go +++ b/pkg/common/storage/database/mgo/object.go @@ -22,7 +22,6 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/tools/db/mongoutil" - "github.com/openimsdk/tools/db/pagination" "github.com/openimsdk/tools/errs" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" @@ -91,21 +90,25 @@ func (o *S3Mongo) Take(ctx context.Context, engine string, name string) (*model. return mongoutil.FindOne[*model.Object](ctx, o.coll, bson.M{"name": name, "engine": engine}) } -func (o *S3Mongo) Delete(ctx context.Context, engine string, name string) error { - return mongoutil.DeleteOne(ctx, o.coll, bson.M{"name": name, "engine": engine}) +func (o *S3Mongo) Delete(ctx context.Context, engine string, name []string) error { + if len(name) == 0 { + return nil + } + return mongoutil.DeleteOne(ctx, o.coll, bson.M{"engine": engine, "name": bson.M{"$in": name}}) } -// Find Expires object -func (o *S3Mongo) FindNeedDeleteObjectByDB(ctx context.Context, duration time.Time, needDelType []string, pagination pagination.Pagination) (total int64, objects []*model.Object, err error) { - return mongoutil.FindPage[*model.Object](ctx, o.coll, bson.M{ - "create_time": bson.M{"$lt": duration}, +func (o *S3Mongo) FindExpirationObject(ctx context.Context, engine string, expiration time.Time, needDelType []string, count int64) ([]*model.Object, error) { + opt := options.Find() + if count > 0 { + opt.SetLimit(count) + } + return mongoutil.Find[*model.Object](ctx, o.coll, bson.M{ + "engine": engine, + "create_time": bson.M{"$lt": expiration}, "group": bson.M{"$in": needDelType}, - }, pagination) + }, opt) } -// Find object by key -func (o *S3Mongo) FindModelsByKey(ctx context.Context, key string) (objects []*model.Object, err error) { - return mongoutil.Find[*model.Object](ctx, o.coll, bson.M{ - "key": key, - }) +func (o *S3Mongo) GetKeyCount(ctx context.Context, engine string, key string) (int64, error) { + return mongoutil.Count(ctx, o.coll, bson.M{"engine": engine, "key": key}) } diff --git a/pkg/common/storage/database/msg.go b/pkg/common/storage/database/msg.go index 23a99f5b96..abb2a44c2f 100644 --- a/pkg/common/storage/database/msg.go +++ b/pkg/common/storage/database/msg.go @@ -45,7 +45,9 @@ type Msg interface { DeleteDoc(ctx context.Context, docID string) error DeleteMsgByIndex(ctx context.Context, docID string, index []int) error - GetBeforeMsg(ctx context.Context, ts int64, docIDs []string, limit int) ([]*model.MsgDocModel, error) + GetRandBeforeMsg(ctx context.Context, ts int64, limit int) ([]*model.MsgDocModel, error) - GetDocIDs(ctx context.Context) ([]string, error) + GetRandDocIDs(ctx context.Context, limit int) ([]string, error) + + GetLastMessageSeqByTime(ctx context.Context, conversationID string, time int64) (int64, error) } diff --git a/pkg/common/storage/database/object.go b/pkg/common/storage/database/object.go index c741e39a60..5541a159b4 100644 --- a/pkg/common/storage/database/object.go +++ b/pkg/common/storage/database/object.go @@ -19,13 +19,12 @@ import ( "time" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "github.com/openimsdk/tools/db/pagination" ) type ObjectInfo interface { SetObject(ctx context.Context, obj *model.Object) error Take(ctx context.Context, engine string, name string) (*model.Object, error) - Delete(ctx context.Context, engine string, name string) error - FindNeedDeleteObjectByDB(ctx context.Context, duration time.Time, needDelType []string, pagination pagination.Pagination) (total int64, objects []*model.Object, err error) - FindModelsByKey(ctx context.Context, key string) (objects []*model.Object, err error) + Delete(ctx context.Context, engine string, name []string) error + FindExpirationObject(ctx context.Context, engine string, expiration time.Time, needDelType []string, count int64) ([]*model.Object, error) + GetKeyCount(ctx context.Context, engine string, key string) (int64, error) } diff --git a/pkg/rpcclient/notification/common.go b/pkg/notification/common_user/common.go similarity index 97% rename from pkg/rpcclient/notification/common.go rename to pkg/notification/common_user/common.go index 09d8b87989..470d9c7a2e 100644 --- a/pkg/rpcclient/notification/common.go +++ b/pkg/notification/common_user/common.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package notification +package common_user type CommonUser interface { GetNickname() string diff --git a/pkg/rpcclient/grouphash/grouphash.go b/pkg/notification/grouphash/grouphash.go similarity index 100% rename from pkg/rpcclient/grouphash/grouphash.go rename to pkg/notification/grouphash/grouphash.go diff --git a/pkg/rpcclient/msg.go b/pkg/notification/msg.go similarity index 97% rename from pkg/rpcclient/msg.go rename to pkg/notification/msg.go index ca9b8fc681..0795982c8c 100644 --- a/pkg/rpcclient/msg.go +++ b/pkg/notification/msg.go @@ -148,17 +148,17 @@ func WithLocalSendMsg(sendMsg func(ctx context.Context, req *msg.SendMsgReq) (*m } } -func WithRpcClient() NotificationSenderOptions { +func WithRpcClient(sendMsg func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error)) NotificationSenderOptions { return func(s *NotificationSender) { s.sendMsg = func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) { - return msg.SendMsgCaller.Invoke(ctx, req) + return sendMsg(ctx, req) } } } -func WithUserRpcClient() NotificationSenderOptions { +func WithUserRpcClient(getUserInfo func(ctx context.Context, userID string) (*sdkws.UserInfo, error)) NotificationSenderOptions { return func(s *NotificationSender) { - s.getUserInfo = GetUserInfo + s.getUserInfo = getUserInfo } } diff --git a/pkg/rpccache/conversation.go b/pkg/rpccache/conversation.go index ba3690f445..70f5acfd10 100644 --- a/pkg/rpccache/conversation.go +++ b/pkg/rpccache/conversation.go @@ -16,12 +16,11 @@ package rpccache import ( "context" - "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" "github.com/openimsdk/open-im-server/v3/pkg/localcache" - pbconv "github.com/openimsdk/protocol/conversation" - "github.com/openimsdk/protocol/rpccall" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" + pbconversation "github.com/openimsdk/protocol/conversation" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/utils/datautil" @@ -33,10 +32,11 @@ const ( conversationWorkerCount = 20 ) -func NewConversationLocalCache(localCache *config.LocalCache, cli redis.UniversalClient) *ConversationLocalCache { +func NewConversationLocalCache(client *rpcli.ConversationClient, localCache *config.LocalCache, cli redis.UniversalClient) *ConversationLocalCache { lc := localCache.Conversation log.ZDebug(context.Background(), "ConversationLocalCache", "topic", lc.Topic, "slotNum", lc.SlotNum, "slotSize", lc.SlotSize, "enable", lc.Enable()) x := &ConversationLocalCache{ + client: client, local: localcache.New[[]byte]( localcache.WithLocalSlotNum(lc.SlotNum), localcache.WithLocalSlotSize(lc.SlotSize), @@ -52,7 +52,8 @@ func NewConversationLocalCache(localCache *config.LocalCache, cli redis.Universa } type ConversationLocalCache struct { - local localcache.Cache[[]byte] + client *rpcli.ConversationClient + local localcache.Cache[[]byte] } func (c *ConversationLocalCache) GetConversationIDs(ctx context.Context, ownerUserID string) (val []string, err error) { @@ -63,7 +64,7 @@ func (c *ConversationLocalCache) GetConversationIDs(ctx context.Context, ownerUs return resp.ConversationIDs, nil } -func (c *ConversationLocalCache) getConversationIDs(ctx context.Context, ownerUserID string) (val *pbconv.GetConversationIDsResp, err error) { +func (c *ConversationLocalCache) getConversationIDs(ctx context.Context, ownerUserID string) (val *pbconversation.GetConversationIDsResp, err error) { log.ZDebug(ctx, "ConversationLocalCache getConversationIDs req", "ownerUserID", ownerUserID) defer func() { if err == nil { @@ -72,14 +73,14 @@ func (c *ConversationLocalCache) getConversationIDs(ctx context.Context, ownerUs log.ZError(ctx, "ConversationLocalCache getConversationIDs return", err, "ownerUserID", ownerUserID) } }() - var cache cacheProto[pbconv.GetConversationIDsResp] + var cache cacheProto[pbconversation.GetConversationIDsResp] return cache.Unmarshal(c.local.Get(ctx, cachekey.GetConversationIDsKey(ownerUserID), func(ctx context.Context) ([]byte, error) { log.ZDebug(ctx, "ConversationLocalCache getConversationIDs rpc", "ownerUserID", ownerUserID) - return cache.Marshal(pbconv.GetConversationIDsCaller.Invoke(ctx, &pbconv.GetConversationIDsReq{UserID: ownerUserID})) + return cache.Marshal(c.client.ConversationClient.GetConversationIDs(ctx, &pbconversation.GetConversationIDsReq{UserID: ownerUserID})) })) } -func (c *ConversationLocalCache) GetConversation(ctx context.Context, userID, conversationID string) (val *pbconv.Conversation, err error) { +func (c *ConversationLocalCache) GetConversation(ctx context.Context, userID, conversationID string) (val *pbconversation.Conversation, err error) { log.ZDebug(ctx, "ConversationLocalCache GetConversation req", "userID", userID, "conversationID", conversationID) defer func() { if err == nil { @@ -88,13 +89,10 @@ func (c *ConversationLocalCache) GetConversation(ctx context.Context, userID, co log.ZWarn(ctx, "ConversationLocalCache GetConversation return", err, "userID", userID, "conversationID", conversationID) } }() - var cache cacheProto[pbconv.Conversation] + var cache cacheProto[pbconversation.Conversation] return cache.Unmarshal(c.local.Get(ctx, cachekey.GetConversationKey(userID, conversationID), func(ctx context.Context) ([]byte, error) { log.ZDebug(ctx, "ConversationLocalCache GetConversation rpc", "userID", userID, "conversationID", conversationID) - return cache.Marshal(rpccall.ExtractField(ctx, pbconv.GetConversationCaller.Invoke, &pbconv.GetConversationReq{ - ConversationID: conversationID, - OwnerUserID: userID, - }, (*pbconv.GetConversationResp).GetConversation)) + return cache.Marshal(c.client.GetConversation(ctx, conversationID, userID)) })) } @@ -106,10 +104,10 @@ func (c *ConversationLocalCache) GetSingleConversationRecvMsgOpt(ctx context.Con return conv.RecvMsgOpt, nil } -func (c *ConversationLocalCache) GetConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*pbconv.Conversation, error) { +func (c *ConversationLocalCache) GetConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*pbconversation.Conversation, error) { var ( - conversations = make([]*pbconv.Conversation, 0, len(conversationIDs)) - conversationsChan = make(chan *pbconv.Conversation, len(conversationIDs)) + conversations = make([]*pbconversation.Conversation, 0, len(conversationIDs)) + conversationsChan = make(chan *pbconversation.Conversation, len(conversationIDs)) ) g, ctx := errgroup.WithContext(ctx) @@ -139,7 +137,7 @@ func (c *ConversationLocalCache) GetConversations(ctx context.Context, ownerUser return conversations, nil } -func (c *ConversationLocalCache) getConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) (val *pbconv.GetConversationNotReceiveMessageUserIDsResp, err error) { +func (c *ConversationLocalCache) getConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) (val *pbconversation.GetConversationNotReceiveMessageUserIDsResp, err error) { log.ZDebug(ctx, "ConversationLocalCache getConversationNotReceiveMessageUserIDs req", "conversationID", conversationID) defer func() { if err == nil { @@ -148,10 +146,10 @@ func (c *ConversationLocalCache) getConversationNotReceiveMessageUserIDs(ctx con log.ZError(ctx, "ConversationLocalCache getConversationNotReceiveMessageUserIDs return", err, "conversationID", conversationID) } }() - var cache cacheProto[pbconv.GetConversationNotReceiveMessageUserIDsResp] + var cache cacheProto[pbconversation.GetConversationNotReceiveMessageUserIDsResp] return cache.Unmarshal(c.local.Get(ctx, cachekey.GetConversationNotReceiveMessageUserIDsKey(conversationID), func(ctx context.Context) ([]byte, error) { log.ZDebug(ctx, "ConversationLocalCache getConversationNotReceiveMessageUserIDs rpc", "conversationID", conversationID) - return cache.Marshal(pbconv.GetConversationNotReceiveMessageUserIDsCaller.Invoke(ctx, &pbconv.GetConversationNotReceiveMessageUserIDsReq{ConversationID: conversationID})) + return cache.Marshal(c.client.ConversationClient.GetConversationNotReceiveMessageUserIDs(ctx, &pbconversation.GetConversationNotReceiveMessageUserIDsReq{ConversationID: conversationID})) })) } diff --git a/pkg/rpccache/friend.go b/pkg/rpccache/friend.go index 865cac7b50..8ed6c1ae9e 100644 --- a/pkg/rpccache/friend.go +++ b/pkg/rpccache/friend.go @@ -16,8 +16,8 @@ package rpccache import ( "context" - "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "github.com/openimsdk/protocol/relation" "github.com/openimsdk/open-im-server/v3/pkg/common/config" @@ -26,10 +26,11 @@ import ( "github.com/redis/go-redis/v9" ) -func NewFriendLocalCache(localCache *config.LocalCache, cli redis.UniversalClient) *FriendLocalCache { +func NewFriendLocalCache(client *rpcli.RelationClient, localCache *config.LocalCache, cli redis.UniversalClient) *FriendLocalCache { lc := localCache.Friend log.ZDebug(context.Background(), "FriendLocalCache", "topic", lc.Topic, "slotNum", lc.SlotNum, "slotSize", lc.SlotSize, "enable", lc.Enable()) x := &FriendLocalCache{ + client: client, local: localcache.New[[]byte]( localcache.WithLocalSlotNum(lc.SlotNum), localcache.WithLocalSlotSize(lc.SlotSize), @@ -45,7 +46,8 @@ func NewFriendLocalCache(localCache *config.LocalCache, cli redis.UniversalClien } type FriendLocalCache struct { - local localcache.Cache[[]byte] + client *rpcli.RelationClient + local localcache.Cache[[]byte] } func (f *FriendLocalCache) IsFriend(ctx context.Context, possibleFriendUserID, userID string) (val bool, err error) { @@ -68,7 +70,7 @@ func (f *FriendLocalCache) isFriend(ctx context.Context, possibleFriendUserID, u var cache cacheProto[relation.IsFriendResp] return cache.Unmarshal(f.local.GetLink(ctx, cachekey.GetIsFriendKey(possibleFriendUserID, userID), func(ctx context.Context) ([]byte, error) { log.ZDebug(ctx, "FriendLocalCache isFriend rpc", "possibleFriendUserID", possibleFriendUserID, "userID", userID) - return cache.Marshal(relation.IsFriendCaller.Invoke(ctx, &relation.IsFriendReq{UserID1: userID, UserID2: possibleFriendUserID})) + return cache.Marshal(f.client.FriendClient.IsFriend(ctx, &relation.IsFriendReq{UserID1: userID, UserID2: possibleFriendUserID})) }, cachekey.GetFriendIDsKey(possibleFriendUserID))) } @@ -94,6 +96,6 @@ func (f *FriendLocalCache) isBlack(ctx context.Context, possibleBlackUserID, use var cache cacheProto[relation.IsBlackResp] return cache.Unmarshal(f.local.GetLink(ctx, cachekey.GetIsBlackIDsKey(possibleBlackUserID, userID), func(ctx context.Context) ([]byte, error) { log.ZDebug(ctx, "FriendLocalCache IsBlack rpc", "possibleBlackUserID", possibleBlackUserID, "userID", userID) - return cache.Marshal(relation.IsBlackCaller.Invoke(ctx, &relation.IsBlackReq{UserID1: possibleBlackUserID, UserID2: userID})) + return cache.Marshal(f.client.FriendClient.IsBlack(ctx, &relation.IsBlackReq{UserID1: possibleBlackUserID, UserID2: userID})) }, cachekey.GetBlackIDsKey(userID))) } diff --git a/pkg/rpccache/group.go b/pkg/rpccache/group.go index 111813103f..174ba7dc5c 100644 --- a/pkg/rpccache/group.go +++ b/pkg/rpccache/group.go @@ -16,10 +16,9 @@ package rpccache import ( "context" - "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "github.com/openimsdk/protocol/group" - "github.com/openimsdk/protocol/rpccall" "github.com/openimsdk/tools/utils/datautil" "github.com/openimsdk/open-im-server/v3/pkg/common/config" @@ -30,10 +29,11 @@ import ( "github.com/redis/go-redis/v9" ) -func NewGroupLocalCache(localCache *config.LocalCache, cli redis.UniversalClient) *GroupLocalCache { +func NewGroupLocalCache(client *rpcli.GroupClient, localCache *config.LocalCache, cli redis.UniversalClient) *GroupLocalCache { lc := localCache.Group log.ZDebug(context.Background(), "GroupLocalCache", "topic", lc.Topic, "slotNum", lc.SlotNum, "slotSize", lc.SlotSize, "enable", lc.Enable()) x := &GroupLocalCache{ + client: client, local: localcache.New[[]byte]( localcache.WithLocalSlotNum(lc.SlotNum), localcache.WithLocalSlotSize(lc.SlotSize), @@ -49,7 +49,8 @@ func NewGroupLocalCache(localCache *config.LocalCache, cli redis.UniversalClient } type GroupLocalCache struct { - local localcache.Cache[[]byte] + client *rpcli.GroupClient + local localcache.Cache[[]byte] } func (g *GroupLocalCache) getGroupMemberIDs(ctx context.Context, groupID string) (val *group.GetGroupMemberUserIDsResp, err error) { @@ -64,7 +65,7 @@ func (g *GroupLocalCache) getGroupMemberIDs(ctx context.Context, groupID string) var cache cacheProto[group.GetGroupMemberUserIDsResp] return cache.Unmarshal(g.local.Get(ctx, cachekey.GetGroupMemberIDsKey(groupID), func(ctx context.Context) ([]byte, error) { log.ZDebug(ctx, "GroupLocalCache getGroupMemberIDs rpc", "groupID", groupID) - return cache.Marshal(group.GetGroupMemberUserIDsCaller.Invoke(ctx, &group.GetGroupMemberUserIDsReq{GroupID: groupID})) + return cache.Marshal(g.client.GroupClient.GetGroupMemberUserIDs(ctx, &group.GetGroupMemberUserIDsReq{GroupID: groupID})) })) } @@ -80,13 +81,7 @@ func (g *GroupLocalCache) GetGroupMember(ctx context.Context, groupID, userID st var cache cacheProto[sdkws.GroupMemberFullInfo] return cache.Unmarshal(g.local.Get(ctx, cachekey.GetGroupMemberInfoKey(groupID, userID), func(ctx context.Context) ([]byte, error) { log.ZDebug(ctx, "GroupLocalCache GetGroupInfo rpc", "groupID", groupID, "userID", userID) - return cache.Marshal(rpccall.ExtractField(ctx, group.GetGroupMemberCacheCaller.Invoke, - &group.GetGroupMemberCacheReq{ - GroupID: groupID, - GroupMemberID: userID, - }, - (*group.GetGroupMemberCacheResp).GetMember, - )) + return cache.Marshal(g.client.GetGroupMemberCache(ctx, groupID, userID)) })) } @@ -102,10 +97,7 @@ func (g *GroupLocalCache) GetGroupInfo(ctx context.Context, groupID string) (val var cache cacheProto[sdkws.GroupInfo] return cache.Unmarshal(g.local.Get(ctx, cachekey.GetGroupInfoKey(groupID), func(ctx context.Context) ([]byte, error) { log.ZDebug(ctx, "GroupLocalCache GetGroupInfo rpc", "groupID", groupID) - return cache.Marshal(rpccall.ExtractField(ctx, group.GetGroupInfoCacheCaller.Invoke, - &group.GetGroupInfoCacheReq{ - GroupID: groupID, - }, (*group.GetGroupInfoCacheResp).GetGroupInfo)) + return cache.Marshal(g.client.GetGroupInfoCache(ctx, groupID)) })) } diff --git a/pkg/rpccache/online.go b/pkg/rpccache/online.go index 25362b5299..8f53234775 100644 --- a/pkg/rpccache/online.go +++ b/pkg/rpccache/online.go @@ -3,16 +3,15 @@ package rpccache import ( "context" "fmt" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" + "github.com/openimsdk/protocol/constant" + "github.com/openimsdk/protocol/user" "math/rand" "strconv" "sync" "sync/atomic" "time" - "github.com/openimsdk/protocol/constant" - "github.com/openimsdk/protocol/rpccall" - "github.com/openimsdk/protocol/user" - "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" "github.com/openimsdk/open-im-server/v3/pkg/localcache" "github.com/openimsdk/open-im-server/v3/pkg/localcache/lru" @@ -23,10 +22,10 @@ import ( "github.com/redis/go-redis/v9" ) -func NewOnlineCache(adminUserID []string, group *GroupLocalCache, rdb redis.UniversalClient, fullUserCache bool, fn func(ctx context.Context, userID string, platformIDs []int32)) (*OnlineCache, error) { +func NewOnlineCache(client *rpcli.UserClient, group *GroupLocalCache, rdb redis.UniversalClient, fullUserCache bool, fn func(ctx context.Context, userID string, platformIDs []int32)) (*OnlineCache, error) { l := &sync.Mutex{} x := &OnlineCache{ - adminUserID: adminUserID, + client: client, group: group, fullUserCache: fullUserCache, Lock: l, @@ -66,8 +65,8 @@ const ( ) type OnlineCache struct { - adminUserID []string - group *GroupLocalCache + client *rpcli.UserClient + group *GroupLocalCache // fullUserCache if enabled, caches the online status of all users using mapCache; // otherwise, only a portion of users' online statuses (regardless of whether they are online) will be cached using lruCache. @@ -113,7 +112,7 @@ func (o *OnlineCache) initUsersOnlineStatus(ctx context.Context) (err error) { cursor := uint64(0) for resp == nil || resp.NextCursor != 0 { if err = retryOperation(func() error { - resp, err = user.GetAllOnlineUsersCaller.Invoke(ctx, &user.GetAllOnlineUsersReq{Cursor: cursor}) + resp, err = o.client.GetAllOnlineUsers(ctx, cursor) if err != nil { return err } @@ -187,17 +186,7 @@ func (o *OnlineCache) doSubscribe(ctx context.Context, rdb redis.UniversalClient func (o *OnlineCache) getUserOnlinePlatform(ctx context.Context, userID string) ([]int32, error) { platformIDs, err := o.lruCache.Get(userID, func() ([]int32, error) { - resp, err := rpccall.ExtractField(ctx, user.GetUserStatusCaller.Invoke, &user.GetUserStatusReq{ - UserID: o.adminUserID[0], - UserIDs: []string{userID}, - }, (*user.GetUserStatusResp).GetStatusList) - if err != nil { - return nil, err - } - if len(resp) == 0 { - return nil, nil - } - return resp[0].PlatformIDs, nil + return o.client.GetUserOnlinePlatform(ctx, userID) }) if err != nil { log.ZError(ctx, "OnlineCache GetUserOnlinePlatform", err, "userID", userID) @@ -238,11 +227,7 @@ func (o *OnlineCache) GetUserOnline(ctx context.Context, userID string) (bool, e func (o *OnlineCache) getUserOnlinePlatformBatch(ctx context.Context, userIDs []string) (map[string][]int32, error) { platformIDsMap, err := o.lruCache.GetBatch(userIDs, func(missingUsers []string) (map[string][]int32, error) { platformIDsMap := make(map[string][]int32) - - usersStatus, err := rpccall.ExtractField(ctx, user.GetUserStatusCaller.Invoke, &user.GetUserStatusReq{ - UserID: o.adminUserID[0], - UserIDs: missingUsers, - }, (*user.GetUserStatusResp).GetStatusList) + usersStatus, err := o.client.GetUsersOnlinePlatform(ctx, missingUsers) if err != nil { return nil, err } diff --git a/pkg/rpccache/subscriber.go b/pkg/rpccache/subscriber.go index 44e1f5885a..d28d1aa295 100644 --- a/pkg/rpccache/subscriber.go +++ b/pkg/rpccache/subscriber.go @@ -17,7 +17,6 @@ package rpccache import ( "context" "encoding/json" - "github.com/openimsdk/tools/log" "github.com/redis/go-redis/v9" ) diff --git a/pkg/rpccache/user.go b/pkg/rpccache/user.go index fce2c911ab..cb0704906b 100644 --- a/pkg/rpccache/user.go +++ b/pkg/rpccache/user.go @@ -16,11 +16,11 @@ package rpccache import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" "github.com/openimsdk/open-im-server/v3/pkg/localcache" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/protocol/user" "github.com/openimsdk/tools/errs" @@ -28,10 +28,11 @@ import ( "github.com/redis/go-redis/v9" ) -func NewUserLocalCache(localCache *config.LocalCache, cli redis.UniversalClient) *UserLocalCache { +func NewUserLocalCache(client *rpcli.UserClient, localCache *config.LocalCache, cli redis.UniversalClient) *UserLocalCache { lc := localCache.User log.ZDebug(context.Background(), "UserLocalCache", "topic", lc.Topic, "slotNum", lc.SlotNum, "slotSize", lc.SlotSize, "enable", lc.Enable()) x := &UserLocalCache{ + client: client, local: localcache.New[[]byte]( localcache.WithLocalSlotNum(lc.SlotNum), localcache.WithLocalSlotSize(lc.SlotSize), @@ -47,7 +48,8 @@ func NewUserLocalCache(localCache *config.LocalCache, cli redis.UniversalClient) } type UserLocalCache struct { - local localcache.Cache[[]byte] + client *rpcli.UserClient + local localcache.Cache[[]byte] } func (u *UserLocalCache) GetUserInfo(ctx context.Context, userID string) (val *sdkws.UserInfo, err error) { @@ -62,7 +64,7 @@ func (u *UserLocalCache) GetUserInfo(ctx context.Context, userID string) (val *s var cache cacheProto[sdkws.UserInfo] return cache.Unmarshal(u.local.Get(ctx, cachekey.GetUserInfoKey(userID), func(ctx context.Context) ([]byte, error) { log.ZDebug(ctx, "UserLocalCache GetUserInfo rpc", "userID", userID) - return cache.Marshal(rpcclient.GetUserInfo(ctx, userID)) + return cache.Marshal(u.client.GetUserInfo(ctx, userID)) })) } @@ -86,7 +88,7 @@ func (u *UserLocalCache) getUserGlobalMsgRecvOpt(ctx context.Context, userID str var cache cacheProto[user.GetGlobalRecvMessageOptResp] return cache.Unmarshal(u.local.Get(ctx, cachekey.GetUserGlobalRecvMsgOptKey(userID), func(ctx context.Context) ([]byte, error) { log.ZDebug(ctx, "UserLocalCache GetUserGlobalMsgRecvOpt rpc", "userID", userID) - return cache.Marshal(user.GetGlobalRecvMessageOptCaller.Invoke(ctx, &user.GetGlobalRecvMessageOptReq{UserID: userID})) + return cache.Marshal(u.client.UserClient.GetGlobalRecvMessageOpt(ctx, &user.GetGlobalRecvMessageOptReq{UserID: userID})) })) } diff --git a/pkg/rpcclient/doc.go b/pkg/rpcclient/doc.go deleted file mode 100644 index 66b0aee91d..0000000000 --- a/pkg/rpcclient/doc.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright © 2024 OpenIM. 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 rpcclient // import "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" diff --git a/pkg/rpcclient/grouphash/doc.go b/pkg/rpcclient/grouphash/doc.go deleted file mode 100644 index c780701d9a..0000000000 --- a/pkg/rpcclient/grouphash/doc.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright © 2024 OpenIM. 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 grouphash // import "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/grouphash" diff --git a/pkg/rpcclient/init.go b/pkg/rpcclient/init.go deleted file mode 100644 index 3d3f68aef8..0000000000 --- a/pkg/rpcclient/init.go +++ /dev/null @@ -1,60 +0,0 @@ -package rpcclient - -import ( - "context" - - "github.com/openimsdk/open-im-server/v3/pkg/common/config" - pbauth "github.com/openimsdk/protocol/auth" - pbconversation "github.com/openimsdk/protocol/conversation" - pbgroup "github.com/openimsdk/protocol/group" - pbmsg "github.com/openimsdk/protocol/msg" - pbmsggateway "github.com/openimsdk/protocol/msggateway" - pbpush "github.com/openimsdk/protocol/push" - pbrelation "github.com/openimsdk/protocol/relation" - pbthird "github.com/openimsdk/protocol/third" - pbuser "github.com/openimsdk/protocol/user" - "github.com/openimsdk/tools/discovery" - "github.com/openimsdk/tools/system/program" - "google.golang.org/grpc" -) - -func InitRpcCaller(discov discovery.SvcDiscoveryRegistry, service config.RpcService) error { - initConn := func(discov discovery.SvcDiscoveryRegistry, name string, initFunc func(conn *grpc.ClientConn)) error { - conn, err := discov.GetConn(context.Background(), name) - if err != nil { - program.ExitWithError(err) - return err - } - initFunc(conn) - return nil - } - if err := initConn(discov, service.Auth, pbauth.InitAuth); err != nil { - return err - } - if err := initConn(discov, service.Conversation, pbconversation.InitConversation); err != nil { - return err - } - if err := initConn(discov, service.Group, pbgroup.InitGroup); err != nil { - return err - } - if err := initConn(discov, service.Msg, pbmsg.InitMsg); err != nil { - return err - } - if err := initConn(discov, service.MessageGateway, pbmsggateway.InitMsgGateway); err != nil { - return err - } - if err := initConn(discov, service.Push, pbpush.InitPushMsgService); err != nil { - return err - } - if err := initConn(discov, service.Friend, pbrelation.InitFriend); err != nil { - return err - } - if err := initConn(discov, service.Third, pbthird.InitThird); err != nil { - return err - } - if err := initConn(discov, service.User, pbuser.InitUser); err != nil { - return err - } - - return nil -} diff --git a/pkg/rpcclient/notification/doc.go b/pkg/rpcclient/notification/doc.go deleted file mode 100644 index 8ce57ca4e8..0000000000 --- a/pkg/rpcclient/notification/doc.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright © 2024 OpenIM. 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 notification // import "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification" diff --git a/pkg/rpcclient/user.go b/pkg/rpcclient/user.go deleted file mode 100644 index 463dd9a390..0000000000 --- a/pkg/rpcclient/user.go +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright © 2023 OpenIM. 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 rpcclient - -import ( - "context" - "strings" - - "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" - "github.com/openimsdk/protocol/sdkws" - "github.com/openimsdk/protocol/user" - "github.com/openimsdk/tools/utils/datautil" -) - -// GetUsersInfo retrieves information for multiple users based on their user IDs. -func GetUsersInfo(ctx context.Context, userIDs []string) ([]*sdkws.UserInfo, error) { - if len(userIDs) == 0 { - return []*sdkws.UserInfo{}, nil - } - resp, err := user.GetDesignateUsersCaller.Invoke(ctx, &user.GetDesignateUsersReq{ - UserIDs: userIDs, - }) - if err != nil { - return nil, err - } - if ids := datautil.Single(userIDs, datautil.Slice(resp.UsersInfo, func(e *sdkws.UserInfo) string { - return e.UserID - })); len(ids) > 0 { - return nil, servererrs.ErrUserIDNotFound.WrapMsg(strings.Join(ids, ",")) - } - return resp.UsersInfo, nil -} - -// GetUserInfo retrieves information for a single user based on the provided user ID. -func GetUserInfo(ctx context.Context, userID string) (*sdkws.UserInfo, error) { - users, err := GetUsersInfo(ctx, []string{userID}) - if err != nil { - return nil, err - } - return users[0], nil -} - -// GetUsersInfoMap retrieves a map of user information indexed by their user IDs. -func GetUsersInfoMap(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error) { - users, err := GetUsersInfo(ctx, userIDs) - if err != nil { - return nil, err - } - return datautil.SliceToMap(users, func(e *sdkws.UserInfo) string { - return e.UserID - }), nil -} - -// GetPublicUserInfos retrieves public information for multiple users based on their user IDs. -func GetPublicUserInfos( - ctx context.Context, - userIDs []string, -) ([]*sdkws.PublicUserInfo, error) { - users, err := GetUsersInfo(ctx, userIDs) - if err != nil { - return nil, err - } - - return datautil.Slice(users, func(e *sdkws.UserInfo) *sdkws.PublicUserInfo { - return &sdkws.PublicUserInfo{ - UserID: e.UserID, - Nickname: e.Nickname, - FaceURL: e.FaceURL, - Ex: e.Ex, - } - }), nil -} - -// GetPublicUserInfo retrieves public information for a single user based on the provided user ID. -func GetPublicUserInfo(ctx context.Context, userID string) (*sdkws.PublicUserInfo, error) { - users, err := GetPublicUserInfos(ctx, []string{userID}) - if err != nil { - return nil, err - } - - return users[0], nil -} - -// GetPublicUserInfoMap retrieves a map of public user information indexed by their user IDs. -func GetPublicUserInfoMap( - ctx context.Context, - userIDs []string, -) (map[string]*sdkws.PublicUserInfo, error) { - users, err := GetPublicUserInfos(ctx, userIDs) - if err != nil { - return nil, err - } - - return datautil.SliceToMap(users, func(e *sdkws.PublicUserInfo) string { - return e.UserID - }), nil -} diff --git a/pkg/rpcli/auth.go b/pkg/rpcli/auth.go new file mode 100644 index 0000000000..17fc6ea286 --- /dev/null +++ b/pkg/rpcli/auth.go @@ -0,0 +1,30 @@ +package rpcli + +import ( + "context" + "github.com/openimsdk/protocol/auth" + "google.golang.org/grpc" +) + +func NewAuthClient(cc grpc.ClientConnInterface) *AuthClient { + return &AuthClient{auth.NewAuthClient(cc)} +} + +type AuthClient struct { + auth.AuthClient +} + +func (x *AuthClient) KickTokens(ctx context.Context, tokens []string) error { + if len(tokens) == 0 { + return nil + } + return ignoreResp(x.AuthClient.KickTokens(ctx, &auth.KickTokensReq{Tokens: tokens})) +} + +func (x *AuthClient) InvalidateToken(ctx context.Context, req *auth.InvalidateTokenReq) error { + return ignoreResp(x.AuthClient.InvalidateToken(ctx, req)) +} + +func (x *AuthClient) ParseToken(ctx context.Context, token string) (*auth.ParseTokenResp, error) { + return x.AuthClient.ParseToken(ctx, &auth.ParseTokenReq{Token: token}) +} diff --git a/pkg/rpcli/conversation.go b/pkg/rpcli/conversation.go new file mode 100644 index 0000000000..ba5b90cb31 --- /dev/null +++ b/pkg/rpcli/conversation.go @@ -0,0 +1,94 @@ +package rpcli + +import ( + "context" + "github.com/openimsdk/protocol/conversation" + "google.golang.org/grpc" +) + +func NewConversationClient(cc grpc.ClientConnInterface) *ConversationClient { + return &ConversationClient{conversation.NewConversationClient(cc)} +} + +type ConversationClient struct { + conversation.ConversationClient +} + +func (x *ConversationClient) SetConversationMaxSeq(ctx context.Context, conversationID string, ownerUserIDs []string, maxSeq int64) error { + if len(ownerUserIDs) == 0 { + return nil + } + req := &conversation.SetConversationMaxSeqReq{ConversationID: conversationID, OwnerUserID: ownerUserIDs, MaxSeq: maxSeq} + return ignoreResp(x.ConversationClient.SetConversationMaxSeq(ctx, req)) +} + +func (x *ConversationClient) SetConversations(ctx context.Context, ownerUserIDs []string, info *conversation.ConversationReq) error { + if len(ownerUserIDs) == 0 { + return nil + } + req := &conversation.SetConversationsReq{UserIDs: ownerUserIDs, Conversation: info} + return ignoreResp(x.ConversationClient.SetConversations(ctx, req)) +} + +func (x *ConversationClient) GetConversationsByConversationIDs(ctx context.Context, conversationIDs []string) ([]*conversation.Conversation, error) { + if len(conversationIDs) == 0 { + return nil, nil + } + req := &conversation.GetConversationsByConversationIDReq{ConversationIDs: conversationIDs} + return extractField(ctx, x.ConversationClient.GetConversationsByConversationID, req, (*conversation.GetConversationsByConversationIDResp).GetConversations) +} + +func (x *ConversationClient) GetConversationsByConversationID(ctx context.Context, conversationID string) (*conversation.Conversation, error) { + return firstValue(x.GetConversationsByConversationIDs(ctx, []string{conversationID})) +} + +func (x *ConversationClient) SetConversationMinSeq(ctx context.Context, conversationID string, ownerUserIDs []string, minSeq int64) error { + if len(ownerUserIDs) == 0 { + return nil + } + req := &conversation.SetConversationMinSeqReq{ConversationID: conversationID, OwnerUserID: ownerUserIDs, MinSeq: minSeq} + return ignoreResp(x.ConversationClient.SetConversationMinSeq(ctx, req)) +} + +func (x *ConversationClient) GetConversation(ctx context.Context, conversationID string, ownerUserID string) (*conversation.Conversation, error) { + req := &conversation.GetConversationReq{ConversationID: conversationID, OwnerUserID: ownerUserID} + return extractField(ctx, x.ConversationClient.GetConversation, req, (*conversation.GetConversationResp).GetConversation) +} + +func (x *ConversationClient) GetConversations(ctx context.Context, conversationIDs []string, ownerUserID string) ([]*conversation.Conversation, error) { + if len(conversationIDs) == 0 { + return nil, nil + } + req := &conversation.GetConversationsReq{ConversationIDs: conversationIDs, OwnerUserID: ownerUserID} + return extractField(ctx, x.ConversationClient.GetConversations, req, (*conversation.GetConversationsResp).GetConversations) +} + +func (x *ConversationClient) GetConversationIDs(ctx context.Context, ownerUserID string) ([]string, error) { + req := &conversation.GetConversationIDsReq{UserID: ownerUserID} + return extractField(ctx, x.ConversationClient.GetConversationIDs, req, (*conversation.GetConversationIDsResp).GetConversationIDs) +} + +func (x *ConversationClient) GetPinnedConversationIDs(ctx context.Context, ownerUserID string) ([]string, error) { + req := &conversation.GetPinnedConversationIDsReq{UserID: ownerUserID} + return extractField(ctx, x.ConversationClient.GetPinnedConversationIDs, req, (*conversation.GetPinnedConversationIDsResp).GetConversationIDs) +} + +func (x *ConversationClient) CreateGroupChatConversations(ctx context.Context, groupID string, userIDs []string) error { + if len(userIDs) == 0 { + return nil + } + req := &conversation.CreateGroupChatConversationsReq{GroupID: groupID, UserIDs: userIDs} + return ignoreResp(x.ConversationClient.CreateGroupChatConversations(ctx, req)) +} + +func (x *ConversationClient) CreateSingleChatConversations(ctx context.Context, req *conversation.CreateSingleChatConversationsReq) error { + return ignoreResp(x.ConversationClient.CreateSingleChatConversations(ctx, req)) +} + +func (x *ConversationClient) GetConversationOfflinePushUserIDs(ctx context.Context, conversationID string, userIDs []string) ([]string, error) { + if len(userIDs) == 0 { + return nil, nil + } + req := &conversation.GetConversationOfflinePushUserIDsReq{ConversationID: conversationID, UserIDs: userIDs} + return extractField(ctx, x.ConversationClient.GetConversationOfflinePushUserIDs, req, (*conversation.GetConversationOfflinePushUserIDsResp).GetUserIDs) +} diff --git a/pkg/rpcli/group.go b/pkg/rpcli/group.go new file mode 100644 index 0000000000..b51283c5dc --- /dev/null +++ b/pkg/rpcli/group.go @@ -0,0 +1,48 @@ +package rpcli + +import ( + "context" + "github.com/openimsdk/protocol/group" + "github.com/openimsdk/protocol/sdkws" + "google.golang.org/grpc" +) + +func NewGroupClient(cc grpc.ClientConnInterface) *GroupClient { + return &GroupClient{group.NewGroupClient(cc)} +} + +type GroupClient struct { + group.GroupClient +} + +func (x *GroupClient) GetGroupsInfo(ctx context.Context, groupIDs []string) ([]*sdkws.GroupInfo, error) { + if len(groupIDs) == 0 { + return nil, nil + } + req := &group.GetGroupsInfoReq{GroupIDs: groupIDs} + return extractField(ctx, x.GroupClient.GetGroupsInfo, req, (*group.GetGroupsInfoResp).GetGroupInfos) +} + +func (x *GroupClient) GetGroupInfo(ctx context.Context, groupID string) (*sdkws.GroupInfo, error) { + return firstValue(x.GetGroupsInfo(ctx, []string{groupID})) +} + +func (x *GroupClient) GetGroupInfoCache(ctx context.Context, groupID string) (*sdkws.GroupInfo, error) { + req := &group.GetGroupInfoCacheReq{GroupID: groupID} + return extractField(ctx, x.GroupClient.GetGroupInfoCache, req, (*group.GetGroupInfoCacheResp).GetGroupInfo) +} + +func (x *GroupClient) GetGroupMemberCache(ctx context.Context, groupID string, userID string) (*sdkws.GroupMemberFullInfo, error) { + req := &group.GetGroupMemberCacheReq{GroupID: groupID, GroupMemberID: userID} + return extractField(ctx, x.GroupClient.GetGroupMemberCache, req, (*group.GetGroupMemberCacheResp).GetMember) +} + +func (x *GroupClient) DismissGroup(ctx context.Context, groupID string, deleteMember bool) error { + req := &group.DismissGroupReq{GroupID: groupID, DeleteMember: deleteMember} + return ignoreResp(x.GroupClient.DismissGroup(ctx, req)) +} + +func (x *GroupClient) GetGroupMemberUserIDs(ctx context.Context, groupID string) ([]string, error) { + req := &group.GetGroupMemberUserIDsReq{GroupID: groupID} + return extractField(ctx, x.GroupClient.GetGroupMemberUserIDs, req, (*group.GetGroupMemberUserIDsResp).GetUserIDs) +} diff --git a/pkg/rpcli/msg.go b/pkg/rpcli/msg.go new file mode 100644 index 0000000000..0c44b7c8b6 --- /dev/null +++ b/pkg/rpcli/msg.go @@ -0,0 +1,90 @@ +package rpcli + +import ( + "context" + "github.com/openimsdk/protocol/msg" + "github.com/openimsdk/protocol/sdkws" + "google.golang.org/grpc" +) + +func NewMsgClient(cc grpc.ClientConnInterface) *MsgClient { + return &MsgClient{msg.NewMsgClient(cc)} +} + +type MsgClient struct { + msg.MsgClient +} + +func (x *MsgClient) GetMaxSeqs(ctx context.Context, conversationIDs []string) (map[string]int64, error) { + if len(conversationIDs) == 0 { + return nil, nil + } + req := &msg.GetMaxSeqsReq{ConversationIDs: conversationIDs} + return extractField(ctx, x.MsgClient.GetMaxSeqs, req, (*msg.SeqsInfoResp).GetMaxSeqs) +} + +func (x *MsgClient) GetMsgByConversationIDs(ctx context.Context, conversationIDs []string, maxSeqs map[string]int64) (map[string]*sdkws.MsgData, error) { + if len(conversationIDs) == 0 || len(maxSeqs) == 0 { + return nil, nil + } + req := &msg.GetMsgByConversationIDsReq{ConversationIDs: conversationIDs, MaxSeqs: maxSeqs} + return extractField(ctx, x.MsgClient.GetMsgByConversationIDs, req, (*msg.GetMsgByConversationIDsResp).GetMsgDatas) +} + +func (x *MsgClient) GetHasReadSeqs(ctx context.Context, conversationIDs []string, userID string) (map[string]int64, error) { + if len(conversationIDs) == 0 { + return nil, nil + } + req := &msg.GetHasReadSeqsReq{ConversationIDs: conversationIDs, UserID: userID} + return extractField(ctx, x.MsgClient.GetHasReadSeqs, req, (*msg.SeqsInfoResp).GetMaxSeqs) +} + +func (x *MsgClient) SetUserConversationMaxSeq(ctx context.Context, conversationID string, ownerUserIDs []string, maxSeq int64) error { + if len(ownerUserIDs) == 0 { + return nil + } + req := &msg.SetUserConversationMaxSeqReq{ConversationID: conversationID, OwnerUserID: ownerUserIDs, MaxSeq: maxSeq} + return ignoreResp(x.MsgClient.SetUserConversationMaxSeq(ctx, req)) +} + +func (x *MsgClient) SetUserConversationMin(ctx context.Context, conversationID string, ownerUserIDs []string, minSeq int64) error { + if len(ownerUserIDs) == 0 { + return nil + } + req := &msg.SetUserConversationsMinSeqReq{ConversationID: conversationID, UserIDs: ownerUserIDs, Seq: minSeq} + return ignoreResp(x.MsgClient.SetUserConversationsMinSeq(ctx, req)) +} + +func (x *MsgClient) GetLastMessageSeqByTime(ctx context.Context, conversationID string, lastTime int64) (int64, error) { + req := &msg.GetLastMessageSeqByTimeReq{ConversationID: conversationID, Time: lastTime} + return extractField(ctx, x.MsgClient.GetLastMessageSeqByTime, req, (*msg.GetLastMessageSeqByTimeResp).GetSeq) +} + +func (x *MsgClient) GetConversationMaxSeq(ctx context.Context, conversationID string) (int64, error) { + req := &msg.GetConversationMaxSeqReq{ConversationID: conversationID} + return extractField(ctx, x.MsgClient.GetConversationMaxSeq, req, (*msg.GetConversationMaxSeqResp).GetMaxSeq) +} + +func (x *MsgClient) GetActiveConversation(ctx context.Context, conversationIDs []string) ([]*msg.ActiveConversation, error) { + if len(conversationIDs) == 0 { + return nil, nil + } + req := &msg.GetActiveConversationReq{ConversationIDs: conversationIDs} + return extractField(ctx, x.MsgClient.GetActiveConversation, req, (*msg.GetActiveConversationResp).GetConversations) +} + +func (x *MsgClient) GetSeqMessage(ctx context.Context, userID string, conversations []*msg.ConversationSeqs) (map[string]*sdkws.PullMsgs, error) { + if len(conversations) == 0 { + return nil, nil + } + req := &msg.GetSeqMessageReq{UserID: userID, Conversations: conversations} + return extractField(ctx, x.MsgClient.GetSeqMessage, req, (*msg.GetSeqMessageResp).GetMsgs) +} + +func (x *MsgClient) SetUserConversationsMinSeq(ctx context.Context, conversationID string, userIDs []string, seq int64) error { + if len(userIDs) == 0 { + return nil + } + req := &msg.SetUserConversationsMinSeqReq{ConversationID: conversationID, UserIDs: userIDs, Seq: seq} + return ignoreResp(x.MsgClient.SetUserConversationsMinSeq(ctx, req)) +} diff --git a/pkg/rpcli/msggateway.go b/pkg/rpcli/msggateway.go new file mode 100644 index 0000000000..3f19963d50 --- /dev/null +++ b/pkg/rpcli/msggateway.go @@ -0,0 +1,14 @@ +package rpcli + +import ( + "github.com/openimsdk/protocol/msggateway" + "google.golang.org/grpc" +) + +func NewMsgGatewayClient(cc grpc.ClientConnInterface) *MsgGatewayClient { + return &MsgGatewayClient{msggateway.NewMsgGatewayClient(cc)} +} + +type MsgGatewayClient struct { + msggateway.MsgGatewayClient +} diff --git a/pkg/rpcli/push.go b/pkg/rpcli/push.go new file mode 100644 index 0000000000..bb33660e40 --- /dev/null +++ b/pkg/rpcli/push.go @@ -0,0 +1,14 @@ +package rpcli + +import ( + "github.com/openimsdk/protocol/push" + "google.golang.org/grpc" +) + +func NewPushMsgServiceClient(cc grpc.ClientConnInterface) *PushMsgServiceClient { + return &PushMsgServiceClient{push.NewPushMsgServiceClient(cc)} +} + +type PushMsgServiceClient struct { + push.PushMsgServiceClient +} diff --git a/pkg/rpcli/relation.go b/pkg/rpcli/relation.go new file mode 100644 index 0000000000..dce0e71656 --- /dev/null +++ b/pkg/rpcli/relation.go @@ -0,0 +1,23 @@ +package rpcli + +import ( + "context" + "github.com/openimsdk/protocol/relation" + "google.golang.org/grpc" +) + +func NewRelationClient(cc grpc.ClientConnInterface) *RelationClient { + return &RelationClient{relation.NewFriendClient(cc)} +} + +type RelationClient struct { + relation.FriendClient +} + +func (x *RelationClient) GetFriendsInfo(ctx context.Context, ownerUserID string, friendUserIDs []string) ([]*relation.FriendInfoOnly, error) { + if len(friendUserIDs) == 0 { + return nil, nil + } + req := &relation.GetFriendInfoReq{OwnerUserID: ownerUserID, FriendUserIDs: friendUserIDs} + return extractField(ctx, x.FriendClient.GetFriendInfo, req, (*relation.GetFriendInfoResp).GetFriendInfos) +} diff --git a/pkg/rpcli/rtc.go b/pkg/rpcli/rtc.go new file mode 100644 index 0000000000..18a79d6b4a --- /dev/null +++ b/pkg/rpcli/rtc.go @@ -0,0 +1,14 @@ +package rpcli + +import ( + "github.com/openimsdk/protocol/rtc" + "google.golang.org/grpc" +) + +func NewRtcServiceClient(cc grpc.ClientConnInterface) *RtcServiceClient { + return &RtcServiceClient{rtc.NewRtcServiceClient(cc)} +} + +type RtcServiceClient struct { + rtc.RtcServiceClient +} diff --git a/pkg/rpcli/third.go b/pkg/rpcli/third.go new file mode 100644 index 0000000000..cbb28ff347 --- /dev/null +++ b/pkg/rpcli/third.go @@ -0,0 +1,14 @@ +package rpcli + +import ( + "github.com/openimsdk/protocol/third" + "google.golang.org/grpc" +) + +func NewThirdClient(cc grpc.ClientConnInterface) *ThirdClient { + return &ThirdClient{third.NewThirdClient(cc)} +} + +type ThirdClient struct { + third.ThirdClient +} diff --git a/pkg/rpcli/tool.go b/pkg/rpcli/tool.go new file mode 100644 index 0000000000..2bd50bd003 --- /dev/null +++ b/pkg/rpcli/tool.go @@ -0,0 +1,32 @@ +package rpcli + +import ( + "context" + "github.com/openimsdk/tools/errs" + "google.golang.org/grpc" +) + +func extractField[A, B, C any](ctx context.Context, fn func(ctx context.Context, req *A, opts ...grpc.CallOption) (*B, error), req *A, get func(*B) C) (C, error) { + resp, err := fn(ctx, req) + if err != nil { + var c C + return c, err + } + return get(resp), nil +} + +func firstValue[A any](val []A, err error) (A, error) { + if err != nil { + var a A + return a, err + } + if len(val) == 0 { + var a A + return a, errs.ErrRecordNotFound.WrapMsg("record not found") + } + return val[0], nil +} + +func ignoreResp(_ any, err error) error { + return err +} diff --git a/pkg/rpcli/user.go b/pkg/rpcli/user.go new file mode 100644 index 0000000000..357640345b --- /dev/null +++ b/pkg/rpcli/user.go @@ -0,0 +1,95 @@ +package rpcli + +import ( + "context" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/protocol/user" + "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/utils/datautil" + "google.golang.org/grpc" +) + +func NewUserClient(cc grpc.ClientConnInterface) *UserClient { + return &UserClient{user.NewUserClient(cc)} +} + +type UserClient struct { + user.UserClient +} + +func (x *UserClient) GetUsersInfo(ctx context.Context, userIDs []string) ([]*sdkws.UserInfo, error) { + if len(userIDs) == 0 { + return nil, nil + } + req := &user.GetDesignateUsersReq{UserIDs: userIDs} + return extractField(ctx, x.UserClient.GetDesignateUsers, req, (*user.GetDesignateUsersResp).GetUsersInfo) +} + +func (x *UserClient) GetUserInfo(ctx context.Context, userID string) (*sdkws.UserInfo, error) { + return firstValue(x.GetUsersInfo(ctx, []string{userID})) +} + +func (x *UserClient) CheckUser(ctx context.Context, userIDs []string) error { + if len(userIDs) == 0 { + return nil + } + users, err := x.GetUsersInfo(ctx, userIDs) + if err != nil { + return err + } + if len(users) != len(userIDs) { + return errs.ErrRecordNotFound.WrapMsg("user not found") + } + return nil +} + +func (x *UserClient) GetUsersInfoMap(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error) { + users, err := x.GetUsersInfo(ctx, userIDs) + if err != nil { + return nil, err + } + return datautil.SliceToMap(users, func(e *sdkws.UserInfo) string { + return e.UserID + }), nil +} + +func (x *UserClient) GetAllOnlineUsers(ctx context.Context, cursor uint64) (*user.GetAllOnlineUsersResp, error) { + req := &user.GetAllOnlineUsersReq{Cursor: cursor} + return x.UserClient.GetAllOnlineUsers(ctx, req) +} + +func (x *UserClient) GetUsersOnlinePlatform(ctx context.Context, userIDs []string) ([]*user.OnlineStatus, error) { + if len(userIDs) == 0 { + return nil, nil + } + req := &user.GetUserStatusReq{UserIDs: userIDs} + return extractField(ctx, x.UserClient.GetUserStatus, req, (*user.GetUserStatusResp).GetStatusList) + +} + +func (x *UserClient) GetUserOnlinePlatform(ctx context.Context, userID string) ([]int32, error) { + status, err := x.GetUsersOnlinePlatform(ctx, []string{userID}) + if err != nil { + return nil, err + } + if len(status) == 0 { + return nil, nil + } + return status[0].PlatformIDs, nil +} + +func (x *UserClient) SetUserOnlineStatus(ctx context.Context, req *user.SetUserOnlineStatusReq) error { + if len(req.Status) == 0 { + return nil + } + return ignoreResp(x.UserClient.SetUserOnlineStatus(ctx, req)) +} + +func (x *UserClient) GetNotificationByID(ctx context.Context, userID string) error { + return ignoreResp(x.UserClient.GetNotificationAccount(ctx, &user.GetNotificationAccountReq{UserID: userID})) +} + +func (x *UserClient) GetAllUserIDs(ctx context.Context, pageNumber, showNumber int32) ([]string, error) { + req := &user.GetAllUserIDReq{Pagination: &sdkws.RequestPagination{PageNumber: pageNumber, ShowNumber: showNumber}} + return extractField(ctx, x.UserClient.GetAllUserID, req, (*user.GetAllUserIDResp).GetUserIDs) +}