diff --git a/README.md b/README.md index 4964bacb5..567dcf8df 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Open-IM-Server +![avatar](https://github.com/OpenIMSDK/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg) ![avatar](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/open-im-logo.png) diff --git a/config/config.yaml b/config/config.yaml index a12f8af3d..923b95591 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -222,6 +222,7 @@ manager: #app管理员userID和对应的secret 建议修改。 用于管理后台登录,也可以用户管理后台对应的api appManagerUid: [ "openIM123456","openIM654321", "openIM333", "openIMAdmin"] secrets: [ "openIM1","openIM2", "openIM333", "openIMAdmin"] + appSysNotificationName: "系统通知" secret: tuoyun # 多端互踢策略 @@ -233,7 +234,7 @@ chatpersistencemysql: true #可靠性存储 reliablestorage: false #消息缓存时间 -msgCacheTimeout: 1800 +msgCacheTimeout: 86400 #群聊已读开启 groupMessageHasReadReceiptEnable: true #单聊已读开启 diff --git a/docker-compose.yaml b/docker-compose.yaml index 52d488f4a..0e180c442 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -99,7 +99,7 @@ services: command: /usr/local/bin/etcd --name etcd0 --data-dir /etcd-data --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://0.0.0.0:2379 --listen-peer-urls http://0.0.0.0:2380 --initial-advertise-peer-urls http://0.0.0.0:2380 --initial-cluster etcd0=http://0.0.0.0:2380 --initial-cluster-token tkn --initial-cluster-state new open_im_server: - image: openim/open_im_server:v2.0.10 + image: openim/open_im_server:v2.1.0 container_name: open_im_server volumes: - ./logs:/Open-IM-Server/logs diff --git a/docs/Wechat.jpg b/docs/Wechat.jpg index d3caf1a44..d6fbe5b0d 100644 Binary files a/docs/Wechat.jpg and b/docs/Wechat.jpg differ diff --git a/internal/demo/register/onboarding_process.go b/internal/demo/register/onboarding_process.go index 62630e126..647fbe3c5 100644 --- a/internal/demo/register/onboarding_process.go +++ b/internal/demo/register/onboarding_process.go @@ -174,7 +174,7 @@ func joinGroups(operationID, userID, userName string, groupIDList []string) { GroupID: groupID, Reason: "register auto join", InvitedUserIDList: []string{userID}, - OpUserID: config.Config.Manager.AppManagerUid[0], + OpUserID: config.Config.Manager.AppManagerUid[1], } resp, err := client.InviteUserToGroup(context.Background(), req) if err != nil { diff --git a/internal/push/logic/push_to_client.go b/internal/push/logic/push_to_client.go index 7f94e7870..ea7a435de 100644 --- a/internal/push/logic/push_to_client.go +++ b/internal/push/logic/push_to_client.go @@ -69,9 +69,11 @@ func MsgToUser(pushMsg *pbPush.PushMsgReq) { return } } - if err := db.DB.HandleSignalInfo(pushMsg.OperationID, pushMsg.MsgData); err != nil { - log.NewError(pushMsg.OperationID, utils.GetSelfFuncName(), err.Error(), pushMsg.MsgData) - return + if pushMsg.MsgData.ContentType == constant.SignalingNotification { + if err := db.DB.HandleSignalInfo(pushMsg.OperationID, pushMsg.MsgData); err != nil { + log.NewError(pushMsg.OperationID, utils.GetSelfFuncName(), err.Error(), pushMsg.MsgData) + return + } } //Use offline push messaging var UIDList []string @@ -153,7 +155,6 @@ func MsgToSuperGroupUser(pushMsg *pbPush.PushMsgReq) { log.NewError(pushMsg.OperationID, errMsg) return } - client := pbCache.NewCacheClient(etcdConn) cacheResp, err := client.GetGroupMemberIDListFromCache(context.Background(), getGroupMemberIDListFromCacheReq) if err != nil { diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index 147e06b63..f51e0edc4 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -849,45 +849,58 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbGroup.JoinGroupReq) func (s *groupServer) QuitGroup(ctx context.Context, req *pbGroup.QuitGroupReq) (*pbGroup.QuitGroupResp, error) { log.NewInfo(req.OperationID, "QuitGroup args ", req.String()) - _, err := imdb.GetGroupMemberInfoByGroupIDAndUserID(req.GroupID, req.OpUserID) + groupInfo, err := imdb.GetGroupInfoByGroupID(req.GroupID) if err != nil { - log.NewError(req.OperationID, "GetGroupMemberInfoByGroupIDAndUserID failed ", err.Error(), req.GroupID, req.OpUserID) + log.NewError(req.OperationID, "ReduceGroupMemberFromCache rpc call failed ", err.Error()) return &pbGroup.QuitGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil } + if groupInfo.GroupType != constant.SuperGroup { + _, err = imdb.GetGroupMemberInfoByGroupIDAndUserID(req.GroupID, req.OpUserID) + if err != nil { + log.NewError(req.OperationID, "GetGroupMemberInfoByGroupIDAndUserID failed ", err.Error(), req.GroupID, req.OpUserID) + return &pbGroup.QuitGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil + } - err = imdb.DeleteGroupMemberByGroupIDAndUserID(req.GroupID, req.OpUserID) - if err != nil { - log.NewError(req.OperationID, "DeleteGroupMemberByGroupIdAndUserId failed ", err.Error(), req.GroupID, req.OpUserID) - return &pbGroup.QuitGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil - } + err = imdb.DeleteGroupMemberByGroupIDAndUserID(req.GroupID, req.OpUserID) + if err != nil { + log.NewError(req.OperationID, "DeleteGroupMemberByGroupIdAndUserId failed ", err.Error(), req.GroupID, req.OpUserID) + return &pbGroup.QuitGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil + } - err = db.DB.DelGroupMember(req.GroupID, req.OpUserID) - if err != nil { - 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, req.OperationID) - if etcdConn == nil { - errMsg := req.OperationID + "getcdv3.GetConn == nil" - log.NewError(req.OperationID, errMsg) - return &pbGroup.QuitGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrInternal.ErrCode, ErrMsg: errMsg}}, nil - } - 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()) + err = db.DB.DelGroupMember(req.GroupID, req.OpUserID) + if err != nil { + 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, req.OperationID) + if etcdConn == nil { + errMsg := req.OperationID + "getcdv3.GetConn == nil" + log.NewError(req.OperationID, errMsg) + return &pbGroup.QuitGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrInternal.ErrCode, ErrMsg: errMsg}}, nil + } + 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()) + } } else { - log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "SetConversation success", respPb.String()) + okUserIDList := []string{req.OpUserID} + if err := db.DB.RemoverUserFromSuperGroup(req.GroupID, okUserIDList); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), req.GroupID, okUserIDList, err.Error()) + return &pbGroup.QuitGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil + } } reduceGroupMemberFromCacheReq := &pbCache.ReduceGroupMemberFromCacheReq{ @@ -896,7 +909,7 @@ func (s *groupServer) QuitGroup(ctx context.Context, req *pbGroup.QuitGroupReq) OperationID: req.OperationID, } etcdConnCache := getcdv3.GetConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImCacheName, req.OperationID) - if etcdConn == nil { + if etcdConnCache == nil { errMsg := req.OperationID + "getcdv3.GetConn == nil" log.NewError(req.OperationID, errMsg) return &pbGroup.QuitGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrInternal.ErrCode, ErrMsg: errMsg}}, nil @@ -912,7 +925,12 @@ func (s *groupServer) QuitGroup(ctx context.Context, req *pbGroup.QuitGroupReq) return &pbGroup.QuitGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil } - chat.MemberQuitNotification(req) + if groupInfo.GroupType != constant.SuperGroup { + chat.MemberQuitNotification(req) + } else { + chat.SuperGroupNotification(req.OperationID, req.OpUserID, req.GroupID) + } + 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 } diff --git a/internal/rpc/msg/group_notification.go b/internal/rpc/msg/group_notification.go index 65aabffb9..258764485 100644 --- a/internal/rpc/msg/group_notification.go +++ b/internal/rpc/msg/group_notification.go @@ -36,7 +36,6 @@ func setOpUserInfo(opUserID, groupID string, groupMemberInfo *open_im_sdk.GroupM return utils.Wrap(err, "") } } - user, err := imdb.GetUserByUserID(opUserID) if err != nil { return utils.Wrap(err, "") @@ -117,15 +116,16 @@ func groupNotification(contentType int32, m proto.Message, sendID, groupID, recv } tips.JsonDetail, _ = marshaler.MarshalToString(m) + var nickname string from, err := imdb.GetUserByUserID(sendID) if err != nil { log.Error(operationID, "GetUserByUserID failed ", err.Error(), sendID) } - nickname := "" if from != nil { nickname = from.Nickname } + to, err := imdb.GetUserByUserID(recvUserID) if err != nil { log.NewWarn(operationID, "GetUserByUserID failed ", err.Error(), recvUserID) diff --git a/pkg/common/config/config.go b/pkg/common/config/config.go index 780ecee9c..2163e7619 100644 --- a/pkg/common/config/config.go +++ b/pkg/common/config/config.go @@ -191,8 +191,9 @@ type config struct { } } Manager struct { - AppManagerUid []string `yaml:"appManagerUid"` - Secrets []string `yaml:"secrets"` + AppManagerUid []string `yaml:"appManagerUid"` + Secrets []string `yaml:"secrets"` + AppSysNotificationName string `yaml:"appSysNotificationName"` } Kafka struct { diff --git a/pkg/common/db/mysql_model/im_mysql_model/user_model.go b/pkg/common/db/mysql_model/im_mysql_model/user_model.go index 8882f6931..1598bac4e 100644 --- a/pkg/common/db/mysql_model/im_mysql_model/user_model.go +++ b/pkg/common/db/mysql_model/im_mysql_model/user_model.go @@ -22,7 +22,11 @@ func init() { } var appMgr db.User appMgr.UserID = v - appMgr.Nickname = "AppManager" + utils.IntToString(k+1) + if k == 0 { + appMgr.Nickname = config.Config.Manager.AppSysNotificationName + } else { + appMgr.Nickname = "AppManager" + utils.IntToString(k+1) + } appMgr.AppMangerLevel = constant.AppAdmin err = UserRegister(appMgr) if err != nil {