mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-10-26 13:12:12 +08:00
Merge: main
This commit is contained in:
commit
5cc018df7d
6
go.mod
6
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
|
||||
|
||||
8
go.sum
8
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=
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
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()
|
||||
|
||||
@ -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)
|
||||
}
|
||||
@ -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) {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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")
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
msgs, err := m.MsgDatabase.GetBeforeMsg(ctx, req.Timestamp, docIDs, getLimit)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if len(msgs) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
for _, msg := range msgs {
|
||||
index, err := m.MsgDatabase.DeleteDocMsgBefore(ctx, req.Timestamp, msg)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if len(index) == 0 {
|
||||
return false, errs.ErrInternalServer.WrapMsg("delete doc msg failed")
|
||||
}
|
||||
|
||||
docNum++
|
||||
msgNum += len(index)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
_, err = destructMsg(ctx)
|
||||
docs, err := m.MsgDatabase.GetRandBeforeMsg(ctx, req.Timestamp, int(req.Limit))
|
||||
if err != nil {
|
||||
log.ZError(ctx, "clear msg failed", err, "docNum", docNum, "msgNum", msgNum, "cost", time.Since(start))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.ZDebug(ctx, "clearing message", "docNum", docNum, "msgNum", msgNum, "cost", time.Since(start))
|
||||
|
||||
return &msg.DestructMsgsResp{}, 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)
|
||||
}
|
||||
for i, doc := range docs {
|
||||
if err := m.MsgDatabase.DeleteDoc(ctx, doc.DocID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.ZDebug(ctx, "DestructMsgs delete doc", "index", i, "docID", doc.DocID)
|
||||
index := strings.LastIndex(doc.DocID, ":")
|
||||
if index < 0 {
|
||||
continue
|
||||
}
|
||||
var minSeq int64
|
||||
for _, model := range doc.Msg {
|
||||
if model.Msg == nil {
|
||||
continue
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if model.Msg.Seq > minSeq {
|
||||
minSeq = model.Msg.Seq
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
return &msg.DestructMsgsResp{Count: int32(len(docs))}, 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
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
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)
|
||||
|
||||
findPagination := &sdkws.RequestPagination{
|
||||
PageNumber: 1,
|
||||
ShowNumber: 500,
|
||||
}
|
||||
|
||||
// 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)
|
||||
models, err := t.s3dataBase.FindExpirationObject(ctx, engine, expireTime, req.ObjectGroup, int64(req.Limit))
|
||||
if err != nil {
|
||||
return nil, 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)
|
||||
}
|
||||
|
||||
// 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 err := t.s3dataBase.DelS3Key(ctx, engine, obj.Name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 := srv.registerClearS3(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := crontab.AddFunc(config.CronTask.CronExecuteTime, clearMsgFunc); err != nil {
|
||||
return errs.Wrap(err)
|
||||
if err := srv.registerDeleteMsg(); 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.registerClearUserMsg(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := crontab.AddFunc(config.CronTask.CronExecuteTime, deleteObjectFunc); err != nil {
|
||||
return errs.Wrap(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")
|
||||
}
|
||||
|
||||
63
internal/tools/cron_test.go
Normal file
63
internal/tools/cron_test.go
Normal file
@ -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()
|
||||
}
|
||||
36
internal/tools/msg.go
Normal file
36
internal/tools/msg.go
Normal file
@ -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)
|
||||
}
|
||||
79
internal/tools/s3.go
Normal file
79
internal/tools/s3.go
Normal file
@ -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}))
|
||||
//}
|
||||
34
internal/tools/user_msg.go
Normal file
34
internal/tools/user_msg.go
Normal file
@ -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)
|
||||
}
|
||||
@ -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,
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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) 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) 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)
|
||||
}
|
||||
|
||||
@ -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,21 +118,19 @@ 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) 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) DeleteObject(ctx context.Context, name string) error {
|
||||
return s.s3.DeleteObject(ctx, name)
|
||||
func (s *s3Database) GetKeyCount(ctx context.Context, engine string, key string) (int64, error) {
|
||||
return s.db.GetKeyCount(ctx, engine, key)
|
||||
}
|
||||
func (s *s3Database) DeleteSpecifiedData(ctx context.Context, engine string, name string) error {
|
||||
|
||||
func (s *s3Database) DeleteSpecifiedData(ctx context.Context, engine string, name []string) error {
|
||||
return s.db.Delete(ctx, engine, name)
|
||||
}
|
||||
|
||||
func (s *s3Database) FindModelsByKey(ctx context.Context, key string) (objects []*model.Object, err error) {
|
||||
return s.db.FindModelsByKey(ctx, key)
|
||||
}
|
||||
|
||||
func (s *s3Database) DelS3Key(ctx context.Context, engine string, keys ...string) error {
|
||||
return s.s3cache.DelS3Key(ctx, engine, keys...)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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())
|
||||
}
|
||||
|
||||
@ -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},
|
||||
"group": bson.M{"$in": needDelType},
|
||||
}, pagination)
|
||||
}
|
||||
|
||||
// Find object by key
|
||||
func (o *S3Mongo) FindModelsByKey(ctx context.Context, key string) (objects []*model.Object, err error) {
|
||||
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{
|
||||
"key": key,
|
||||
})
|
||||
"engine": engine,
|
||||
"create_time": bson.M{"$lt": expiration},
|
||||
"group": bson.M{"$in": needDelType},
|
||||
}, opt)
|
||||
}
|
||||
|
||||
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})
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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}))
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
@ -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)))
|
||||
}
|
||||
|
||||
@ -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))
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -17,7 +17,6 @@ package rpccache
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/openimsdk/tools/log"
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
@ -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}))
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
@ -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"
|
||||
@ -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"
|
||||
@ -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
|
||||
}
|
||||
@ -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"
|
||||
@ -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
|
||||
}
|
||||
30
pkg/rpcli/auth.go
Normal file
30
pkg/rpcli/auth.go
Normal file
@ -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})
|
||||
}
|
||||
94
pkg/rpcli/conversation.go
Normal file
94
pkg/rpcli/conversation.go
Normal file
@ -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)
|
||||
}
|
||||
48
pkg/rpcli/group.go
Normal file
48
pkg/rpcli/group.go
Normal file
@ -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)
|
||||
}
|
||||
90
pkg/rpcli/msg.go
Normal file
90
pkg/rpcli/msg.go
Normal file
@ -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))
|
||||
}
|
||||
14
pkg/rpcli/msggateway.go
Normal file
14
pkg/rpcli/msggateway.go
Normal file
@ -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
|
||||
}
|
||||
14
pkg/rpcli/push.go
Normal file
14
pkg/rpcli/push.go
Normal file
@ -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
|
||||
}
|
||||
23
pkg/rpcli/relation.go
Normal file
23
pkg/rpcli/relation.go
Normal file
@ -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)
|
||||
}
|
||||
14
pkg/rpcli/rtc.go
Normal file
14
pkg/rpcli/rtc.go
Normal file
@ -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
|
||||
}
|
||||
14
pkg/rpcli/third.go
Normal file
14
pkg/rpcli/third.go
Normal file
@ -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
|
||||
}
|
||||
32
pkg/rpcli/tool.go
Normal file
32
pkg/rpcli/tool.go
Normal file
@ -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
|
||||
}
|
||||
95
pkg/rpcli/user.go
Normal file
95
pkg/rpcli/user.go
Normal file
@ -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)
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user