Merge remote-tracking branch 'origin/tuoyun' into tuoyun

This commit is contained in:
skiffer-git
2022-04-26 09:09:44 +08:00
52 changed files with 2877 additions and 741 deletions
+103
View File
@@ -0,0 +1,103 @@
package cache
import (
"Open_IM/pkg/common/config"
"Open_IM/pkg/common/constant"
"Open_IM/pkg/common/db"
"Open_IM/pkg/common/log"
"Open_IM/pkg/grpc-etcdv3/getcdv3"
pbCache "Open_IM/pkg/proto/cache"
commonPb "Open_IM/pkg/proto/sdk_ws"
"Open_IM/pkg/utils"
"context"
"google.golang.org/grpc"
"net"
"strconv"
"strings"
)
type cacheServer struct {
rpcPort int
rpcRegisterName string
etcdSchema string
etcdAddr []string
}
func NewOfficeServer(port int) *cacheServer {
log.NewPrivateLog(constant.LogFileName)
return &cacheServer{
rpcPort: port,
rpcRegisterName: config.Config.RpcRegisterName.OpenImOfficeName,
etcdSchema: config.Config.Etcd.EtcdSchema,
etcdAddr: config.Config.Etcd.EtcdAddr,
}
}
func (s *cacheServer) Run() {
log.NewInfo("0", "cacheServer rpc start ")
ip := utils.ServerIP
registerAddress := ip + ":" + strconv.Itoa(s.rpcPort)
//listener network
listener, err := net.Listen("tcp", registerAddress)
if err != nil {
log.NewError("0", "Listen failed ", err.Error(), registerAddress)
return
}
log.NewInfo("0", "listen network success, ", registerAddress, listener)
defer listener.Close()
//grpc server
srv := grpc.NewServer()
defer srv.GracefulStop()
pbCache.RegisterCacheServer(srv, s)
err = getcdv3.RegisterEtcd(s.etcdSchema, strings.Join(s.etcdAddr, ","), ip, s.rpcPort, s.rpcRegisterName, 10)
if err != nil {
log.NewError("0", "RegisterEtcd failed ", err.Error())
return
}
err = srv.Serve(listener)
if err != nil {
log.NewError("0", "Serve failed ", err.Error())
return
}
log.NewInfo("0", "message cms rpc success")
}
func (s *cacheServer) GetUserInfo(_ context.Context, req *pbCache.GetUserInfoReq) (resp *pbCache.GetUserInfoResp, err error) {
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String())
resp = &pbCache.GetUserInfoResp{
UserInfoList: []*commonPb.UserInfo{},
CommonResp: &pbCache.CommonResp{},
}
for _, userID := range req.UserIDList {
userInfo, err := db.DB.GetUserInfo(userID)
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "get userInfo from cache failed", err.Error())
continue
}
resp.UserInfoList = append(resp.UserInfoList, userInfo)
}
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String())
return resp, nil
}
func (s *cacheServer) UpdateUserInfo(_ context.Context, req *pbCache.UpdateUserInfoReq) (resp *pbCache.UpdateUserInfoResp, err error) {
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String())
resp = &pbCache.UpdateUserInfoResp{
CommonResp: &pbCache.CommonResp{},
}
for _, userInfo := range req.UserInfoList {
if err := db.DB.SetUserInfo(userInfo); err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "set userInfo to cache failed", err.Error())
return resp, nil
}
}
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String())
return resp, nil
}
func (s *cacheServer) UpdateAllUserToCache(_ context.Context, req *pbCache.UpdateAllUserToCacheReq) (resp *pbCache.UpdateAllUserToCacheResp, err error) {
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String())
resp = &pbCache.UpdateAllUserToCacheResp{CommonResp: &pbCache.CommonResp{}}
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String())
return resp, nil
}
+167
View File
@@ -0,0 +1,167 @@
package conversation
import (
chat "Open_IM/internal/rpc/msg"
"Open_IM/pkg/common/constant"
"Open_IM/pkg/common/db"
imdb "Open_IM/pkg/common/db/mysql_model/im_mysql_model"
"Open_IM/pkg/common/log"
"Open_IM/pkg/grpc-etcdv3/getcdv3"
pbConversation "Open_IM/pkg/proto/conversation"
"Open_IM/pkg/utils"
"context"
"net"
"strconv"
"strings"
"Open_IM/pkg/common/config"
"google.golang.org/grpc"
)
type rpcConversation struct {
rpcPort int
rpcRegisterName string
etcdSchema string
etcdAddr []string
}
func (rpc *rpcConversation) ModifyConversationField(c context.Context, req *pbConversation.ModifyConversationFieldReq) (*pbConversation.ModifyConversationFieldResp, error) {
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String())
resp := &pbConversation.ModifyConversationFieldResp{}
var err error
if req.Conversation.ConversationType == constant.GroupChatType {
groupInfo, err := imdb.GetGroupInfoByGroupID(req.Conversation.GroupID)
if err != nil {
log.NewError(req.OperationID, "GetGroupInfoByGroupID failed ", req.Conversation.GroupID, err.Error())
resp.CommonResp = &pbConversation.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}
return resp, nil
}
if groupInfo.Status == constant.GroupStatusDismissed && !req.Conversation.IsNotInGroup {
errMsg := "group status is dismissed"
resp.CommonResp = &pbConversation.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: errMsg}
return resp, nil
}
}
var conversation db.Conversation
if err := utils.CopyStructFields(&conversation, req.Conversation); err != nil {
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "CopyStructFields failed", *req.Conversation, err.Error())
}
haveUserID, _ := imdb.GetExistConversationUserIDList(req.UserIDList, req.Conversation.ConversationID)
switch req.FieldType {
case constant.FieldRecvMsgOpt:
for _, v := range req.UserIDList {
if err = db.DB.SetSingleConversationRecvMsgOpt(v, req.Conversation.ConversationID, req.Conversation.RecvMsgOpt); err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "cache failed, rpc return", err.Error())
resp.CommonResp = &pbConversation.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}
return resp, nil
}
}
err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"recv_msg_opt": conversation.RecvMsgOpt})
case constant.FieldGroupAtType:
err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"group_at_type": conversation.GroupAtType})
case constant.FieldIsNotInGroup:
err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"is_not_in_group": conversation.IsNotInGroup})
case constant.FieldIsPinned:
err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"is_pinned": conversation.IsPinned})
case constant.FieldIsPrivateChat:
err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"is_private_chat": conversation.IsPrivateChat})
case constant.FieldEx:
err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"ex": conversation.Ex})
case constant.FieldAttachedInfo:
err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"attached_info": conversation.AttachedInfo})
}
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "UpdateColumnsConversations error", err.Error())
resp.CommonResp = &pbConversation.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}
return resp, nil
}
for _, v := range utils.DifferenceString(haveUserID, req.UserIDList) {
conversation.OwnerUserID = v
err := imdb.SetOneConversation(conversation)
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "SetConversation error", err.Error())
resp.CommonResp = &pbConversation.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}
return resp, nil
}
}
// notification
if req.Conversation.ConversationType == constant.SingleChatType && req.FieldType == constant.FieldIsPrivateChat {
//sync peer user conversation if conversation is singleChatType
if err := syncPeerUserConversation(req.Conversation, req.OperationID); err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "syncPeerUserConversation", err.Error())
resp.CommonResp = &pbConversation.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}
return resp, nil
}
} else {
for _, v := range req.UserIDList {
chat.ConversationChangeNotification(req.OperationID, v)
}
}
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "rpc return", resp.String())
resp.CommonResp = &pbConversation.CommonResp{}
return resp, nil
}
func syncPeerUserConversation(conversation *pbConversation.Conversation, operationID string) error {
peerUserConversation := db.Conversation{
OwnerUserID: conversation.UserID,
ConversationID: utils.GetConversationIDBySessionType(conversation.OwnerUserID, constant.SingleChatType),
ConversationType: constant.SingleChatType,
UserID: conversation.OwnerUserID,
GroupID: "",
RecvMsgOpt: 0,
UnreadCount: 0,
DraftTextTime: 0,
IsPinned: false,
IsPrivateChat: conversation.IsPrivateChat,
AttachedInfo: "",
Ex: "",
}
err := imdb.PeerUserSetConversation(peerUserConversation)
if err != nil {
log.NewError(operationID, utils.GetSelfFuncName(), "SetConversation error", err.Error())
return err
}
chat.ConversationSetPrivateNotification(operationID, conversation.OwnerUserID, conversation.UserID, conversation.IsPrivateChat)
return nil
}
func NewRpcConversationServer(port int) *rpcConversation {
log.NewPrivateLog(constant.LogFileName)
return &rpcConversation{
rpcPort: port,
rpcRegisterName: config.Config.RpcRegisterName.OpenImConversationName,
etcdSchema: config.Config.Etcd.EtcdSchema,
etcdAddr: config.Config.Etcd.EtcdAddr,
}
}
func (rpc *rpcConversation) Run() {
log.NewInfo("0", "rpc conversation start...")
address := utils.ServerIP + ":" + strconv.Itoa(rpc.rpcPort)
listener, err := net.Listen("tcp", address)
if err != nil {
log.NewError("0", "listen network failed ", err.Error(), address)
return
}
log.NewInfo("0", "listen network success, ", address, listener)
//grpc server
srv := grpc.NewServer()
defer srv.GracefulStop()
//service registers with etcd
pbConversation.RegisterConversationServer(srv, rpc)
err = getcdv3.RegisterEtcd(rpc.etcdSchema, strings.Join(rpc.etcdAddr, ","), utils.ServerIP, rpc.rpcPort, rpc.rpcRegisterName, 10)
if err != nil {
log.NewError("0", "RegisterEtcd failed ", err.Error(),
rpc.etcdSchema, strings.Join(rpc.etcdAddr, ","), utils.ServerIP, rpc.rpcPort, rpc.rpcRegisterName)
return
}
log.NewInfo("0", "RegisterConversationServer ok ", rpc.etcdSchema, strings.Join(rpc.etcdAddr, ","), utils.ServerIP, rpc.rpcPort, rpc.rpcRegisterName)
err = srv.Serve(listener)
if err != nil {
log.NewError("0", "Serve failed ", err.Error())
return
}
log.NewInfo("0", "rpc conversation ok")
}
+164 -6
View File
@@ -13,6 +13,7 @@ import (
"Open_IM/pkg/grpc-etcdv3/getcdv3"
pbGroup "Open_IM/pkg/proto/group"
open_im_sdk "Open_IM/pkg/proto/sdk_ws"
pbUser "Open_IM/pkg/proto/user"
"Open_IM/pkg/utils"
"context"
"net"
@@ -258,7 +259,53 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbGroup.Invite
}
resp.Id2ResultList = append(resp.Id2ResultList, &resultNode)
}
var haveConUserID []string
conversations, err := imdb.GetConversationsByConversationIDMultipleOwner(okUserIDList, utils.GetConversationIDBySessionType(req.GroupID, constant.GroupChatType))
for _, v := range conversations {
haveConUserID = append(haveConUserID, v.OwnerUserID)
}
var reqPb pbUser.SetConversationReq
var c pbUser.Conversation
for _, v := range conversations {
reqPb.OperationID = req.OperationID
c.OwnerUserID = v.OwnerUserID
c.ConversationID = utils.GetConversationIDBySessionType(req.GroupID, constant.GroupChatType)
c.RecvMsgOpt = v.RecvMsgOpt
c.ConversationType = constant.GroupChatType
c.GroupID = req.GroupID
c.IsPinned = v.IsPinned
c.AttachedInfo = v.AttachedInfo
c.IsPrivateChat = v.IsPrivateChat
c.GroupAtType = v.GroupAtType
c.IsNotInGroup = false
c.Ex = v.Ex
reqPb.Conversation = &c
etcdConn := getcdv3.GetConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImUserName)
client := pbUser.NewUserClient(etcdConn)
respPb, err := client.SetConversation(context.Background(), &reqPb)
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "SetConversation rpc failed, ", reqPb.String(), err.Error(), v.OwnerUserID)
} else {
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "SetConversation success", respPb.String(), v.OwnerUserID)
}
}
for _, v := range utils.DifferenceString(haveConUserID, okUserIDList) {
reqPb.OperationID = req.OperationID
c.OwnerUserID = v
c.ConversationID = utils.GetConversationIDBySessionType(req.GroupID, constant.GroupChatType)
c.ConversationType = constant.GroupChatType
c.GroupID = req.GroupID
c.IsNotInGroup = false
reqPb.Conversation = &c
etcdConn := getcdv3.GetConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImUserName)
client := pbUser.NewUserClient(etcdConn)
respPb, err := client.SetConversation(context.Background(), &reqPb)
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "SetConversation rpc failed, ", reqPb.String(), err.Error(), v)
} else {
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "SetConversation success", respPb.String(), v)
}
}
chat.MemberInvitedNotification(req.OperationID, req.GroupID, req.OpUserID, req.Reason, okUserIDList)
resp.ErrCode = 0
log.NewInfo(req.OperationID, "InviteUserToGroup rpc return ", resp.String())
@@ -378,9 +425,28 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbGroup.KickGrou
okUserIDList = append(okUserIDList, v)
}
err = db.DB.DelGroupMember(req.GroupID, v)
//err = db.DB.DelGroupMember(req.GroupID, v)
//if err != nil {
// log.NewError(req.OperationID, "DelGroupMember failed ", err.Error(), req.GroupID, v)
//}
}
var reqPb pbUser.SetConversationReq
var c pbUser.Conversation
for _, v := range okUserIDList {
reqPb.OperationID = req.OperationID
c.OwnerUserID = v
c.ConversationID = utils.GetConversationIDBySessionType(req.GroupID, constant.GroupChatType)
c.ConversationType = constant.GroupChatType
c.GroupID = req.GroupID
c.IsNotInGroup = true
reqPb.Conversation = &c
etcdConn := getcdv3.GetConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImUserName)
client := pbUser.NewUserClient(etcdConn)
respPb, err := client.SetConversation(context.Background(), &reqPb)
if err != nil {
log.NewError(req.OperationID, "DelGroupMember failed ", err.Error(), req.GroupID, v)
log.NewError(req.OperationID, utils.GetSelfFuncName(), "SetConversation rpc failed, ", reqPb.String(), err.Error(), v)
} else {
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "SetConversation success", respPb.String(), v)
}
}
chat.MemberKickedNotification(req, okUserIDList)
@@ -501,6 +567,38 @@ func (s *groupServer) GroupApplicationResponse(_ context.Context, req *pbGroup.G
log.NewError(req.OperationID, "GroupApplicationResponse failed ", err.Error(), member)
return &pbGroup.GroupApplicationResponseResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil
}
var reqPb pbUser.SetConversationReq
reqPb.OperationID = req.OperationID
var c pbUser.Conversation
conversation, err := imdb.GetConversation(req.FromUserID, utils.GetConversationIDBySessionType(req.GroupID, constant.GroupChatType))
if err != nil {
c.OwnerUserID = req.FromUserID
c.ConversationID = utils.GetConversationIDBySessionType(req.GroupID, constant.GroupChatType)
c.ConversationType = constant.GroupChatType
c.GroupID = req.GroupID
c.IsNotInGroup = false
} else {
c.OwnerUserID = conversation.OwnerUserID
c.ConversationID = utils.GetConversationIDBySessionType(req.GroupID, constant.GroupChatType)
c.RecvMsgOpt = conversation.RecvMsgOpt
c.ConversationType = constant.GroupChatType
c.GroupID = req.GroupID
c.IsPinned = conversation.IsPinned
c.AttachedInfo = conversation.AttachedInfo
c.IsPrivateChat = conversation.IsPrivateChat
c.GroupAtType = conversation.GroupAtType
c.IsNotInGroup = false
c.Ex = conversation.Ex
}
reqPb.Conversation = &c
etcdConn := getcdv3.GetConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImUserName)
client := pbUser.NewUserClient(etcdConn)
respPb, err := client.SetConversation(context.Background(), &reqPb)
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "SetConversation rpc failed, ", reqPb.String(), err.Error())
} else {
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "SetConversation success", respPb.String())
}
chat.GroupApplicationAcceptedNotification(req)
chat.MemberEnterNotification(req)
} else if req.HandleResult == constant.GroupResponseRefuse {
@@ -556,7 +654,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbGroup.JoinGroupReq)
}
func (s *groupServer) QuitGroup(ctx context.Context, req *pbGroup.QuitGroupReq) (*pbGroup.QuitGroupResp, error) {
log.NewError(req.OperationID, "QuitGroup args ", req.String())
log.NewInfo(req.OperationID, "QuitGroup args ", req.String())
_, err := imdb.GetGroupMemberInfoByGroupIDAndUserID(req.GroupID, req.OpUserID)
if err != nil {
log.NewError(req.OperationID, "GetGroupMemberInfoByGroupIDAndUserID failed ", err.Error(), req.GroupID, req.OpUserID)
@@ -574,7 +672,24 @@ func (s *groupServer) QuitGroup(ctx context.Context, req *pbGroup.QuitGroupReq)
log.NewError(req.OperationID, "DelGroupMember failed ", req.GroupID, req.OpUserID)
// return &pbGroup.CommonResp{ErrorCode: constant.ErrQuitGroup.ErrCode, ErrorMsg: constant.ErrQuitGroup.ErrMsg}, nil
}
//modify quitter conversation info
var reqPb pbUser.SetConversationReq
var c pbUser.Conversation
reqPb.OperationID = req.OperationID
c.OwnerUserID = req.OpUserID
c.ConversationID = utils.GetConversationIDBySessionType(req.GroupID, constant.GroupChatType)
c.ConversationType = constant.GroupChatType
c.GroupID = req.GroupID
c.IsNotInGroup = true
reqPb.Conversation = &c
etcdConn := getcdv3.GetConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImUserName)
client := pbUser.NewUserClient(etcdConn)
respPb, err := client.SetConversation(context.Background(), &reqPb)
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "SetConversation rpc failed, ", reqPb.String(), err.Error())
} else {
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "SetConversation success", respPb.String())
}
chat.MemberQuitNotification(req)
log.NewInfo(req.OperationID, "rpc QuitGroup return ", pbGroup.QuitGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: 0, ErrMsg: ""}})
return &pbGroup.QuitGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: 0, ErrMsg: ""}}, nil
@@ -896,6 +1011,25 @@ func (s *groupServer) RemoveGroupMembersCMS(_ context.Context, req *pbGroup.Remo
OperationID: req.OperationID,
OpUserID: req.OpUserId,
}
var reqPb pbUser.SetConversationReq
var c pbUser.Conversation
for _, v := range resp.Success {
reqPb.OperationID = req.OperationID
c.OwnerUserID = v
c.ConversationID = utils.GetConversationIDBySessionType(req.GroupId, constant.GroupChatType)
c.ConversationType = constant.GroupChatType
c.GroupID = req.GroupId
c.IsNotInGroup = true
reqPb.Conversation = &c
etcdConn := getcdv3.GetConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImUserName)
client := pbUser.NewUserClient(etcdConn)
respPb, err := client.SetConversation(context.Background(), &reqPb)
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "SetConversation rpc failed, ", reqPb.String(), err.Error(), v)
} else {
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "SetConversation success", respPb.String(), v)
}
}
chat.MemberKickedNotification(reqKick, resp.Success)
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "success: ", resp.Success)
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "failed: ", resp.Failed)
@@ -987,14 +1121,38 @@ func (s *groupServer) DismissGroup(ctx context.Context, req *pbGroup.DismissGrou
log.NewError(req.OperationID, "OperateGroupStatus failed ", req.GroupID, constant.GroupStatusDismissed)
return &pbGroup.DismissGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil
}
memberList, err := imdb.GetGroupMemberListByGroupID(req.GroupID)
if err != nil {
log.NewError(req.OperationID, "GetGroupMemberListByGroupID failed,", err.Error(), req.GroupID)
}
//modify quitter conversation info
var reqPb pbUser.SetConversationReq
var c pbUser.Conversation
for _, v := range memberList {
reqPb.OperationID = req.OperationID
c.OwnerUserID = v.UserID
c.ConversationID = utils.GetConversationIDBySessionType(req.GroupID, constant.GroupChatType)
c.ConversationType = constant.GroupChatType
c.GroupID = req.GroupID
c.IsNotInGroup = true
reqPb.Conversation = &c
etcdConn := getcdv3.GetConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImUserName)
client := pbUser.NewUserClient(etcdConn)
respPb, err := client.SetConversation(context.Background(), &reqPb)
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "SetConversation rpc failed, ", reqPb.String(), err.Error(), v.UserID)
} else {
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "SetConversation success", respPb.String(), v.UserID)
}
}
chat.GroupDismissedNotification(req)
err = imdb.DeleteGroupMemberByGroupID(req.GroupID)
if err != nil {
log.NewError(req.OperationID, "DeleteGroupMemberByGroupID failed ", req.GroupID)
return &pbGroup.DismissGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil
}
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "rpc return ", pbGroup.CommonResp{ErrCode: 0, ErrMsg: ""})
return &pbGroup.DismissGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: 0, ErrMsg: ""}}, nil
}
+77 -5
View File
@@ -7,6 +7,7 @@ import (
"Open_IM/pkg/common/log"
"Open_IM/pkg/grpc-etcdv3/getcdv3"
pbChat "Open_IM/pkg/proto/chat"
pbConversation "Open_IM/pkg/proto/conversation"
rpc "Open_IM/pkg/proto/friend"
pbGroup "Open_IM/pkg/proto/group"
sdk_ws "Open_IM/pkg/proto/sdk_ws"
@@ -227,6 +228,12 @@ func (rpc *rpcChat) SendMsg(_ context.Context, pb *pbChat.SendMsgReq) (*pbChat.S
log.Error(pb.Token, pb.OperationID, "rpc send_msg getGroupInfo failed, err = %s", reply.ErrMsg)
return returnMsg(&replay, pb, reply.ErrCode, reply.ErrMsg, "", 0)
}
memberUserIDList := func(all []*sdk_ws.GroupMemberFullInfo) (result []string) {
for _, v := range all {
result = append(result, v.UserID)
}
return result
}(reply.MemberList)
var addUidList []string
switch pb.MsgData.ContentType {
case constant.MemberKickedNotification:
@@ -246,17 +253,67 @@ func (rpc *rpcChat) SendMsg(_ context.Context, pb *pbChat.SendMsgReq) (*pbChat.S
}
case constant.MemberQuitNotification:
addUidList = append(addUidList, pb.MsgData.SendID)
case constant.AtText:
go func() {
var conversationReq pbConversation.ModifyConversationFieldReq
var tag bool
var atUserID []string
conversation := pbConversation.Conversation{
OwnerUserID: pb.MsgData.SendID,
ConversationID: utils.GetConversationIDBySessionType(pb.MsgData.GroupID, constant.GroupChatType),
ConversationType: constant.GroupChatType,
GroupID: pb.MsgData.GroupID,
}
conversationReq.Conversation = &conversation
conversationReq.OperationID = pb.OperationID
conversationReq.FieldType = constant.FieldGroupAtType
tagAll := utils.IsContain(constant.AtAllString, pb.MsgData.AtUserIDList)
if tagAll {
atUserID = utils.DifferenceString([]string{constant.AtAllString}, pb.MsgData.AtUserIDList)
if len(atUserID) == 0 { //just @everyone
conversationReq.UserIDList = memberUserIDList
conversation.GroupAtType = constant.AtAll
} else { //@Everyone and @other people
conversationReq.UserIDList = atUserID
conversation.GroupAtType = constant.AtAllAtMe
tag = true
}
} else {
conversationReq.UserIDList = pb.MsgData.AtUserIDList
conversation.GroupAtType = constant.AtMe
}
etcdConn := getcdv3.GetConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImConversationName)
client := pbConversation.NewConversationClient(etcdConn)
conversationReply, err := client.ModifyConversationField(context.Background(), &conversationReq)
if err != nil {
log.NewError(conversationReq.OperationID, "ModifyConversationField rpc failed, ", conversationReq.String(), err.Error())
} else if conversationReply.CommonResp.ErrCode != 0 {
log.NewError(conversationReq.OperationID, "ModifyConversationField rpc failed, ", conversationReq.String(), conversationReply.String())
}
if tag {
conversationReq.UserIDList = utils.DifferenceString(atUserID, memberUserIDList)
conversation.GroupAtType = constant.AtAll
etcdConn := getcdv3.GetConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImConversationName)
client := pbConversation.NewConversationClient(etcdConn)
conversationReply, err := client.ModifyConversationField(context.Background(), &conversationReq)
if err != nil {
log.NewError(conversationReq.OperationID, "ModifyConversationField rpc failed, ", conversationReq.String(), err.Error())
} else if conversationReply.CommonResp.ErrCode != 0 {
log.NewError(conversationReq.OperationID, "ModifyConversationField rpc failed, ", conversationReq.String(), conversationReply.String())
}
}
}()
default:
}
groupID := pb.MsgData.GroupID
for _, v := range reply.MemberList {
pb.MsgData.RecvID = v.UserID
isSend := modifyMessageByUserMessageReceiveOpt(v.UserID, groupID, constant.GroupChatType, pb)
for _, v := range memberUserIDList {
pb.MsgData.RecvID = v
isSend := modifyMessageByUserMessageReceiveOpt(v, groupID, constant.GroupChatType, pb)
if isSend {
msgToMQ.MsgData = pb.MsgData
err := rpc.sendMsgToKafka(&msgToMQ, v.UserID)
err := rpc.sendMsgToKafka(&msgToMQ, v)
if err != nil {
log.NewError(msgToMQ.OperationID, "kafka send msg err:UserId", v.UserID, msgToMQ.String())
log.NewError(msgToMQ.OperationID, "kafka send msg err:UserId", v, msgToMQ.String())
return returnMsg(&replay, pb, 201, "kafka send msg err", "", 0)
}
}
@@ -579,6 +636,21 @@ func Notification(n *NotificationMsg) {
reliabilityLevel = config.Config.Notification.OrganizationChanged.Conversation.ReliabilityLevel
unReadCount = config.Config.Notification.OrganizationChanged.Conversation.UnreadCount
case constant.WorkMomentNotification:
pushSwitch = config.Config.Notification.WorkMomentsNotification.OfflinePush.PushSwitch
title = config.Config.Notification.WorkMomentsNotification.OfflinePush.Title
desc = config.Config.Notification.WorkMomentsNotification.OfflinePush.Desc
ex = config.Config.Notification.WorkMomentsNotification.OfflinePush.Ext
reliabilityLevel = config.Config.Notification.WorkMomentsNotification.Conversation.ReliabilityLevel
unReadCount = config.Config.Notification.WorkMomentsNotification.Conversation.UnreadCount
case constant.ConversationPrivateChatNotification:
pushSwitch = config.Config.Notification.ConversationSetPrivate.OfflinePush.PushSwitch
title = config.Config.Notification.ConversationSetPrivate.OfflinePush.Title
desc = config.Config.Notification.ConversationSetPrivate.OfflinePush.Desc
ex = config.Config.Notification.ConversationSetPrivate.OfflinePush.Ext
reliabilityLevel = config.Config.Notification.ConversationSetPrivate.Conversation.ReliabilityLevel
unReadCount = config.Config.Notification.ConversationSetPrivate.Conversation.UnreadCount
}
switch reliabilityLevel {
case constant.UnreliableNotification:
+23 -9
View File
@@ -4,28 +4,42 @@ import (
"Open_IM/pkg/common/constant"
"Open_IM/pkg/common/log"
pbOffice "Open_IM/pkg/proto/office"
sdk "Open_IM/pkg/proto/sdk_ws"
"Open_IM/pkg/utils"
"github.com/golang/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
)
func WorkMomentSendNotification(operationID, sendID, recvID string, notificationMsg *pbOffice.WorkMomentNotificationMsg) {
log.NewInfo(operationID, utils.GetSelfFuncName(), recvID)
bytes, err := proto.Marshal(notificationMsg)
if err != nil {
log.NewError(operationID, utils.GetSelfFuncName(), "proto marshal failed", err.Error())
}
WorkMomentNotification(operationID, sendID, recvID, bytes)
log.NewInfo(operationID, utils.GetSelfFuncName(), sendID, recvID, notificationMsg)
//if sendID == recvID {
// return
//}
WorkMomentNotification(operationID, sendID, recvID, notificationMsg)
}
func WorkMomentNotification(operationID, sendID, recvID string, content []byte) {
func WorkMomentNotification(operationID, sendID, recvID string, m proto.Message) {
var tips sdk.TipsComm
var err error
marshaler := jsonpb.Marshaler{
OrigName: true,
EnumsAsInts: false,
EmitDefaults: false,
}
tips.JsonDetail, _ = marshaler.MarshalToString(m)
n := &NotificationMsg{
SendID: sendID,
RecvID: recvID,
Content: content,
MsgFrom: constant.UserMsgType,
ContentType: constant.WorkMomentNotification,
SessionType: constant.UserMsgType,
SessionType: constant.SingleChatType,
OperationID: operationID,
}
n.Content, err = proto.Marshal(&tips)
if err != nil {
log.NewError(operationID, utils.GetSelfFuncName(), "proto.Marshal failed")
return
}
log.NewInfo(operationID, utils.GetSelfFuncName(), string(n.Content))
Notification(n)
}
+42 -41
View File
@@ -280,23 +280,12 @@ func (s *officeServer) CreateOneWorkMoment(_ context.Context, req *pbOffice.Crea
resp.CommonResp = &pbOffice.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}
return resp, nil
}
workMoment.UserName = createUser.Nickname
workMoment.FaceURL = createUser.FaceURL
if err := utils.CopyStructFields(&workMoment, req.WorkMoment); err != nil {
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "CopyStructFields failed", err.Error())
}
workMoment.PermissionUserIDList = s.getPermissionUserIDList(req.OperationID, req.WorkMoment.PermissionGroupIDList, req.WorkMoment.PermissionUserIDList)
for _, userID := range req.WorkMoment.AtUserIDList {
userName, err := imdb.GetUserNameByUserID(userID)
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetUserNameByUserID failed", userID, err.Error())
continue
}
workMoment.AtUserList = append(workMoment.AtUserList, &db.AtUser{
UserID: userID,
UserName: userName,
})
}
workMoment.UserName = createUser.Nickname
workMoment.FaceURL = createUser.FaceURL
workMoment.PermissionUserIDList = s.getPermissionUserIDList(req.OperationID, req.WorkMoment.PermissionGroupList, req.WorkMoment.PermissionUserList)
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "workMoment to create", workMoment)
err = db.DB.CreateOneWorkMoment(&workMoment)
if err != nil {
@@ -306,7 +295,7 @@ func (s *officeServer) CreateOneWorkMoment(_ context.Context, req *pbOffice.Crea
}
// send notification to at users
for _, atUser := range req.WorkMoment.AtUserIDList {
for _, atUser := range req.WorkMoment.AtUserList {
workMomentNotificationMsg := &pbOffice.WorkMomentNotificationMsg{
NotificationMsgType: constant.WorkMomentAtUserNotification,
WorkMomentID: workMoment.WorkMomentID,
@@ -314,24 +303,29 @@ func (s *officeServer) CreateOneWorkMoment(_ context.Context, req *pbOffice.Crea
UserID: workMoment.UserID,
FaceURL: createUser.FaceURL,
UserName: createUser.Nickname,
CreateTime: workMoment.CreateTime,
}
msg.WorkMomentSendNotification(req.OperationID, workMoment.UserID, atUser, workMomentNotificationMsg)
msg.WorkMomentSendNotification(req.OperationID, workMoment.UserID, atUser.UserID, workMomentNotificationMsg)
}
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String())
return resp, nil
}
// count and distinct permission users
func (s *officeServer) getPermissionUserIDList(operationID string, groupIDList, userIDList []string) []string {
func (s *officeServer) getPermissionUserIDList(operationID string, groupList []*pbOffice.PermissionGroup, userList []*pbOffice.WorkMomentUser) []string {
var permissionUserIDList []string
for _, groupID := range groupIDList {
GroupMemberIDList, err := imdb.GetGroupMemberIDListByGroupID(groupID)
for _, group := range groupList {
GroupMemberIDList, err := imdb.GetGroupMemberIDListByGroupID(group.GroupID)
if err != nil {
log.NewError(operationID, utils.GetSelfFuncName(), "GetGroupMemberIDListByGroupID failed", groupID, err.Error())
log.NewError(operationID, utils.GetSelfFuncName(), "GetGroupMemberIDListByGroupID failed", group, err.Error())
continue
}
permissionUserIDList = append(permissionUserIDList, GroupMemberIDList...)
}
var userIDList []string
for _, user := range userList {
userIDList = append(userIDList, user.UserID)
}
permissionUserIDList = append(permissionUserIDList, userIDList...)
permissionUserIDList = utils.RemoveRepeatedStringInList(permissionUserIDList)
return permissionUserIDList
@@ -382,13 +376,13 @@ func isUserCanSeeWorkMoment(userID string, workMoment db.WorkMoment) bool {
func (s *officeServer) LikeOneWorkMoment(_ context.Context, req *pbOffice.LikeOneWorkMomentReq) (resp *pbOffice.LikeOneWorkMomentResp, err error) {
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String())
resp = &pbOffice.LikeOneWorkMomentResp{CommonResp: &pbOffice.CommonResp{}}
userName, err := imdb.GetUserNameByUserID(req.UserID)
user, err := imdb.GetUserByUserID(req.UserID)
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetUserNameByUserID failed", err.Error())
resp.CommonResp = &pbOffice.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}
return resp, nil
}
workMoment, err := db.DB.LikeOneWorkMoment(req.UserID, userName, req.WorkMomentID)
workMoment, like, err := db.DB.LikeOneWorkMoment(req.UserID, user.Nickname, req.WorkMomentID)
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "LikeOneWorkMoment failed ", err.Error())
resp.CommonResp = &pbOffice.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}
@@ -398,10 +392,15 @@ func (s *officeServer) LikeOneWorkMoment(_ context.Context, req *pbOffice.LikeOn
NotificationMsgType: constant.WorkMomentLikeNotification,
WorkMomentID: workMoment.WorkMomentID,
WorkMomentContent: workMoment.Content,
UserID: workMoment.UserID,
UserID: user.UserID,
FaceURL: user.FaceURL,
UserName: user.Nickname,
CreateTime: int32(time.Now().Unix()),
}
// send notification
msg.WorkMomentSendNotification(req.OperationID, req.UserID, workMoment.UserID, workMomentNotificationMsg)
if like {
msg.WorkMomentSendNotification(req.OperationID, req.UserID, workMoment.UserID, workMomentNotificationMsg)
}
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String())
return resp, nil
}
@@ -443,16 +442,13 @@ func (s *officeServer) CommentOneWorkMoment(_ context.Context, req *pbOffice.Com
WorkMomentID: workMoment.WorkMomentID,
WorkMomentContent: workMoment.Content,
UserID: workMoment.UserID,
Comment: &pbOffice.Comment{
UserID: comment.UserID,
UserName: comment.UserName,
FaceURL: commentUser.FaceURL,
ReplyUserID: comment.ReplyUserID,
ReplyUserName: comment.ReplyUserName,
ContentID: comment.ContentID,
Content: comment.Content,
CreateTime: comment.CreateTime,
},
FaceURL: workMoment.FaceURL,
UserName: workMoment.UserName,
ReplyUserID: comment.ReplyUserID,
ReplyUserName: comment.ReplyUserName,
ContentID: comment.ContentID,
Content: comment.Content,
CreateTime: comment.CreateTime,
}
msg.WorkMomentSendNotification(req.OperationID, req.UserID, workMoment.UserID, workMomentNotificationMsg)
if req.ReplyUserID != "" {
@@ -489,17 +485,21 @@ func (s *officeServer) GetWorkMomentByID(_ context.Context, req *pbOffice.GetWor
func (s *officeServer) GetUserWorkMoments(_ context.Context, req *pbOffice.GetUserWorkMomentsReq) (resp *pbOffice.GetUserWorkMomentsResp, err error) {
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String())
resp = &pbOffice.GetUserWorkMomentsResp{CommonResp: &pbOffice.CommonResp{}, WorkMoments: []*pbOffice.WorkMoment{}}
//resp.WorkMoments = make([]*pbOffice.WorkMoment, 0)
workMoments, err := db.DB.GetUserWorkMoments(req.UserID, req.Pagination.ShowNumber, req.Pagination.PageNumber)
resp.Pagination = &pbCommon.ResponsePagination{CurrentPage: req.Pagination.PageNumber, ShowNumber: req.Pagination.ShowNumber}
var workMoments []db.WorkMoment
if req.UserID == req.OpUserID {
workMoments, err = db.DB.GetUserSelfWorkMoments(req.UserID, req.Pagination.ShowNumber, req.Pagination.PageNumber)
} else {
workMoments, err = db.DB.GetUserWorkMoments(req.OpUserID, req.UserID, req.Pagination.ShowNumber, req.Pagination.PageNumber)
}
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), err)
log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetUserWorkMoments failed", err.Error())
resp.CommonResp = &pbOffice.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}
return resp, nil
}
if err := utils.CopyStructFields(&resp.WorkMoments, workMoments); err != nil {
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "CopyStructFields failed", err.Error())
}
resp.Pagination = &pbCommon.ResponsePagination{CurrentPage: req.Pagination.PageNumber, ShowNumber: req.Pagination.ShowNumber}
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String())
return resp, nil
}
@@ -507,14 +507,16 @@ func (s *officeServer) GetUserWorkMoments(_ context.Context, req *pbOffice.GetUs
func (s *officeServer) GetUserFriendWorkMoments(_ context.Context, req *pbOffice.GetUserFriendWorkMomentsReq) (resp *pbOffice.GetUserFriendWorkMomentsResp, err error) {
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String())
resp = &pbOffice.GetUserFriendWorkMomentsResp{CommonResp: &pbOffice.CommonResp{}, WorkMoments: []*pbOffice.WorkMoment{}}
//resp.WorkMoments = make([]*pbOffice.WorkMoment, 0)
resp.Pagination = &pbCommon.ResponsePagination{CurrentPage: req.Pagination.PageNumber, ShowNumber: req.Pagination.ShowNumber}
friendIDList, err := imdb.GetFriendIDListByUserID(req.UserID)
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetFriendIDListByUserID", err.Error())
resp.CommonResp = &pbOffice.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}
return resp, nil
}
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "friendIDList: ", friendIDList)
for _, friendID := range friendIDList {
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), friendID)
}
workMoments, err := db.DB.GetUserFriendWorkMoments(friendIDList, req.Pagination.ShowNumber, req.Pagination.PageNumber, req.UserID)
if err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetUserFriendWorkMoments", err.Error())
@@ -524,7 +526,6 @@ func (s *officeServer) GetUserFriendWorkMoments(_ context.Context, req *pbOffice
if err := utils.CopyStructFields(&resp.WorkMoments, workMoments); err != nil {
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "CopyStructFields failed", err.Error())
}
resp.Pagination = &pbCommon.ResponsePagination{CurrentPage: req.Pagination.PageNumber, ShowNumber: req.Pagination.ShowNumber}
log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String())
return resp, nil
}
+3 -2
View File
@@ -75,7 +75,7 @@ func (s *userServer) Run() {
func syncPeerUserConversation(conversation *pbUser.Conversation, operationID string) error {
peerUserConversation := db.Conversation{
OwnerUserID: conversation.UserID,
ConversationID: "single_" + conversation.OwnerUserID,
ConversationID: utils.GetConversationIDBySessionType(conversation.OwnerUserID, constant.SingleChatType),
ConversationType: constant.SingleChatType,
UserID: conversation.OwnerUserID,
GroupID: "",
@@ -129,6 +129,7 @@ func (s *userServer) BatchSetConversations(ctx context.Context, req *pbUser.Batc
if err := utils.CopyStructFields(&conversation, v); err != nil {
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), v.String(), "CopyStructFields failed", err.Error())
}
//redis op
if err := db.DB.SetSingleConversationRecvMsgOpt(req.OwnerUserID, v.ConversationID, v.RecvMsgOpt); err != nil {
log.NewError(req.OperationID, utils.GetSelfFuncName(), "cache failed, rpc return", err.Error())
resp.CommonResp = &pbUser.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}
@@ -217,7 +218,7 @@ func (s *userServer) SetConversation(ctx context.Context, req *pbUser.SetConvers
resp.CommonResp = &pbUser.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}
return resp, nil
}
if groupInfo.Status == constant.GroupStatusDismissed {
if groupInfo.Status == constant.GroupStatusDismissed && !req.Conversation.IsNotInGroup {
errMsg := "group status is dismissed"
resp.CommonResp = &pbUser.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: errMsg}
return resp, nil