416 lines
11 KiB
Go
416 lines
11 KiB
Go
package chat
|
|
|
|
import (
|
|
"context"
|
|
"go_dreamfactory/comm"
|
|
"go_dreamfactory/lego/base"
|
|
"go_dreamfactory/lego/core"
|
|
"go_dreamfactory/lego/sys/event"
|
|
"go_dreamfactory/lego/sys/log"
|
|
"go_dreamfactory/lego/utils/codec/json"
|
|
"go_dreamfactory/modules"
|
|
"go_dreamfactory/pb"
|
|
"go_dreamfactory/sys/configure"
|
|
"time"
|
|
|
|
"google.golang.org/protobuf/types/known/anypb"
|
|
)
|
|
|
|
const moduleName = "聊天"
|
|
|
|
/*
|
|
模块名:论坛
|
|
描述:处理跨服社交论坛相关业务
|
|
开发:李伟
|
|
*/
|
|
func NewModule() core.IModule {
|
|
m := new(Chat)
|
|
return m
|
|
}
|
|
|
|
type Chat struct {
|
|
modules.ModuleBase
|
|
service base.IRPCXService //rpc服务对象 通过这个对象可以发布服务和调用其他服务的接口
|
|
options *Options
|
|
gm comm.IGm //gm模块
|
|
sociaty comm.ISociaty //工会模块
|
|
api_comp *apiComp
|
|
configure *configureComp
|
|
modelChat *modelChatComp
|
|
}
|
|
|
|
// 重构模块配置对象
|
|
func (this *Chat) NewOptions() (options core.IModuleOptions) {
|
|
return new(Options)
|
|
}
|
|
|
|
// 模块名
|
|
func (this *Chat) GetType() core.M_Modules {
|
|
return comm.ModuleChat
|
|
}
|
|
|
|
// 模块初始化接口 注册用户创建角色事件
|
|
func (this *Chat) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
|
|
err = this.ModuleBase.Init(service, module, options)
|
|
this.service = service.(base.IRPCXService)
|
|
this.options = options.(*Options)
|
|
return
|
|
}
|
|
|
|
func (this *Chat) Start() (err error) {
|
|
err = this.ModuleBase.Start()
|
|
var module core.IModule
|
|
if module, err = this.service.GetModule(comm.ModuleGM); err != nil {
|
|
return
|
|
}
|
|
this.gm = module.(comm.IGm)
|
|
if module, err = this.service.GetModule(comm.ModuleSociaty); err != nil {
|
|
return
|
|
}
|
|
this.sociaty = module.(comm.ISociaty)
|
|
event.RegisterGO(comm.EventUserOffline, this.EventUserOffline)
|
|
this.service.RegisterFunctionName(string(comm.Rpc_ModuleChatPushChat), this.Rpc_ModuleChatPushChat)
|
|
return
|
|
}
|
|
|
|
// 装备组件
|
|
func (this *Chat) OnInstallComp() {
|
|
this.ModuleBase.OnInstallComp()
|
|
this.api_comp = this.RegisterComp(new(apiComp)).(*apiComp)
|
|
this.modelChat = this.RegisterComp(new(modelChatComp)).(*modelChatComp)
|
|
this.configure = this.RegisterComp(new(configureComp)).(*configureComp)
|
|
}
|
|
|
|
// Event------------------------------------------------------------------------------------------------------------
|
|
func (this *Chat) EventUserOffline(uid, sessionid string) {
|
|
if err := this.modelChat.removeCrossChannelMember(uid); err != nil {
|
|
this.Error("EventUserOffline", log.Field{Key: "uid", Value: uid}, log.Field{Key: "err", Value: err.Error()})
|
|
}
|
|
}
|
|
|
|
// RPC--------------------------------------------------------------------------------------------------------------
|
|
// 推送聊天消息
|
|
func (this *Chat) Rpc_ModuleChatPushChat(ctx context.Context, args *pb.DBChat, reply *pb.EmptyResp) (err error) {
|
|
var (
|
|
max_chat int32
|
|
)
|
|
if max_chat, err = this.configure.GetChannelRecordMax(); err != nil {
|
|
this.Errorln(err)
|
|
return
|
|
}
|
|
switch args.Channel {
|
|
case pb.ChatChannel_World:
|
|
if err = this.modelChat.sendChatToWorld(args, max_chat); err != nil {
|
|
this.Errorln(err)
|
|
return
|
|
}
|
|
break
|
|
case pb.ChatChannel_Union:
|
|
if err = this.modelChat.sendChatToUnion(args, max_chat); err != nil {
|
|
this.Errorln(err)
|
|
return
|
|
}
|
|
break
|
|
case pb.ChatChannel_Private:
|
|
if err = this.modelChat.sendChatToPrivate(args); err != nil {
|
|
this.Errorln(err)
|
|
return
|
|
}
|
|
break
|
|
case pb.ChatChannel_CrossServer:
|
|
if err = this.modelChat.sendChatToCrossServer(args, max_chat); err != nil {
|
|
this.Errorln(err)
|
|
return
|
|
}
|
|
break
|
|
case pb.ChatChannel_System:
|
|
if err = this.modelChat.sendChatToSystem(args); err != nil {
|
|
this.Errorln(err)
|
|
return
|
|
}
|
|
break
|
|
}
|
|
return
|
|
}
|
|
|
|
// 对外接口----------------------------------------------------------------------------------------------------------
|
|
// 向世界频道发送聊天消息
|
|
func (this *Chat) SendWorldChat(msg *pb.DBChat) (errdata *pb.ErrorData) {
|
|
var (
|
|
max_chat int32
|
|
err error
|
|
)
|
|
if max_chat, err = this.configure.GetChannelRecordMax(); err != nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_ConfigNoFound,
|
|
Title: pb.ErrorCode_ConfigNoFound.ToString(),
|
|
Message: err.Error(),
|
|
}
|
|
this.Errorln(err)
|
|
return
|
|
}
|
|
if this.IsCross() {
|
|
if err = this.modelChat.sendChatToWorld(msg, max_chat); err != nil {
|
|
this.Errorln(err)
|
|
return
|
|
}
|
|
} else {
|
|
if _, err = this.service.AcrossClusterRpcGo(
|
|
context.Background(),
|
|
this.GetCrossTag(),
|
|
comm.Service_Worker,
|
|
string(comm.Rpc_ModuleChatPushChat),
|
|
msg,
|
|
nil); err != nil {
|
|
this.Errorln(err)
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_RpcFuncExecutionError,
|
|
Title: pb.ErrorCode_RpcFuncExecutionError.ToString(),
|
|
Message: err.Error(),
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// 向工会发送聊天消息
|
|
func (this *Chat) SendUnionChat(msg *pb.DBChat) (errdata *pb.ErrorData) {
|
|
var (
|
|
max_chat int32
|
|
err error
|
|
)
|
|
if max_chat, err = this.configure.GetChannelRecordMax(); err != nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_ConfigNoFound,
|
|
Title: pb.ErrorCode_ConfigNoFound.ToString(),
|
|
Message: err.Error(),
|
|
}
|
|
this.Errorln(err)
|
|
return
|
|
}
|
|
if this.IsCross() {
|
|
if err = this.modelChat.sendChatToUnion(msg, max_chat); err != nil {
|
|
this.Errorln(err)
|
|
return
|
|
}
|
|
} else {
|
|
if _, err = this.service.AcrossClusterRpcGo(
|
|
context.Background(),
|
|
this.GetCrossTag(),
|
|
comm.Service_Worker,
|
|
string(comm.Rpc_ModuleChatPushChat),
|
|
msg,
|
|
nil); err != nil {
|
|
this.Errorln(err)
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_RpcFuncExecutionError,
|
|
Title: pb.ErrorCode_RpcFuncExecutionError.ToString(),
|
|
Message: err.Error(),
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// 向个人发送聊天消息
|
|
func (this *Chat) SendUserChat(msg *pb.DBChat) (errdata *pb.ErrorData) {
|
|
var (
|
|
err error
|
|
session comm.IUserSession
|
|
ok bool
|
|
)
|
|
defer func() {
|
|
this.PutUserSession(session)
|
|
}()
|
|
if session, ok = this.GetUserSession(msg.Ruid); ok {
|
|
session.SendMsg(string(this.GetType()), "message", &pb.ChatMessagePush{Chat: msg})
|
|
if err = session.Push(); err != nil {
|
|
this.Errorf("err:%v", err)
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_SystemError,
|
|
Title: pb.ErrorCode_SystemError.ToString(),
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
} else {
|
|
if err = this.modelChat.saveUserMsg(msg); err != nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_DBError,
|
|
Title: pb.ErrorCode_DBError.ToString(),
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// 广播系统消息
|
|
func (this *Chat) SendSysChatToWorld(ctype comm.ChatSystemType, appenddata interface{}, value0 int32, value1 int32, agrs ...string) (errdata *pb.ErrorData) {
|
|
var (
|
|
jsonStr []byte
|
|
err error
|
|
)
|
|
if st, ok := this.configure.GetCheckChatSystem(int32(ctype), value0, value1); ok {
|
|
msg := &pb.DBChat{
|
|
Channel: pb.ChatChannel_System,
|
|
Ctype: pb.ChatType_Text,
|
|
Stag: this.service.GetTag(),
|
|
Ctime: configure.Now().Unix(),
|
|
Content: "",
|
|
Display: st.Display,
|
|
AppendInt: int64(st.Key),
|
|
AppendStrs: agrs,
|
|
}
|
|
switch ctype {
|
|
case comm.ChatSystem3:
|
|
msg.Ctype = pb.ChatType_Share
|
|
if appenddata != nil {
|
|
if jsonStr, err = json.Marshal(appenddata); err != nil {
|
|
this.Errorf("err:%v", err)
|
|
} else {
|
|
data := map[string]interface{}{
|
|
agrs[1]: map[string]interface{}{
|
|
"key": agrs[1],
|
|
"appendStr": string(jsonStr),
|
|
"itemType": pb.ChatType_EquipmentShare,
|
|
},
|
|
}
|
|
jsonStr, _ = json.Marshal(data)
|
|
msg.AppendStr = string(jsonStr)
|
|
}
|
|
}
|
|
case comm.ChatSystem7, comm.ChatSystem8, comm.ChatSystem9, comm.ChatSystem10, comm.ChatSystem11:
|
|
msg.Ctype = pb.ChatType_Share
|
|
if appenddata != nil {
|
|
if jsonStr, err = json.Marshal(appenddata); err != nil {
|
|
this.Errorf("err:%v", err)
|
|
} else {
|
|
data := map[string]interface{}{
|
|
agrs[1]: map[string]interface{}{
|
|
"key": agrs[1],
|
|
"appendStr": string(jsonStr),
|
|
"itemType": pb.ChatType_HeroShare,
|
|
},
|
|
}
|
|
jsonStr, _ = json.Marshal(data)
|
|
msg.AppendStr = string(jsonStr)
|
|
}
|
|
}
|
|
}
|
|
|
|
if this.IsCross() {
|
|
if err = this.modelChat.sendChatToSystem(msg); err != nil {
|
|
this.Errorln(err)
|
|
return
|
|
}
|
|
} else {
|
|
if _, err = this.service.AcrossClusterRpcGo(
|
|
context.Background(),
|
|
this.GetCrossTag(),
|
|
comm.Service_Worker,
|
|
string(comm.Rpc_ModuleChatPushChat),
|
|
msg,
|
|
nil); err != nil {
|
|
this.Errorln(err)
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_RpcFuncExecutionError,
|
|
Title: pb.ErrorCode_RpcFuncExecutionError.ToString(),
|
|
Message: err.Error(),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// 广播系统消息
|
|
func (this *Chat) SendSysChatToUser(session comm.IUserSession, ctype comm.ChatSystemType, value0, value1 int32, agrs ...string) (errdata *pb.ErrorData) {
|
|
if st, ok := this.configure.GetCheckChatSystem(int32(ctype), value0, value1); ok {
|
|
msg := &pb.DBChat{
|
|
Channel: pb.ChatChannel_System,
|
|
Ctime: time.Now().Unix(),
|
|
AppendInt: int64(st.Key),
|
|
}
|
|
session.SendMsg(string(this.GetType()), "message", &pb.ChatMessagePush{Chat: msg})
|
|
}
|
|
return
|
|
}
|
|
|
|
// Push--------------------------------------------------------------------------------------------------------------
|
|
// 推送消息到世界
|
|
func (this *Chat) pushChatToWorld(msg *pb.DBChat) (err error) {
|
|
data, _ := anypb.New(&pb.ChatMessagePush{Chat: msg})
|
|
if err = this.service.AcrossClusterBroadcast(context.Background(), msg.Stag, comm.Service_Gateway, string(comm.Rpc_GatewaySendRadioMsg), pb.UserMessage{
|
|
MainType: string(this.GetType()),
|
|
SubType: "message",
|
|
Data: data,
|
|
}, nil); err != nil {
|
|
this.Errorf("err:%v", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
// 推送消息到工会
|
|
func (this *Chat) pushChatToUnion(msg *pb.DBChat) (err error) {
|
|
if members := this.sociaty.MembersBySociatyId(msg.UnionId); members != nil {
|
|
users := make([]string, 0, len(members))
|
|
for _, v := range members {
|
|
if v.OfflineTime == 0 { //离线时间为0 表示在线
|
|
users = append(users, v.Uid)
|
|
}
|
|
}
|
|
this.SendMsgToUsers(string(this.GetType()), "message", &pb.ChatMessagePush{Chat: msg}, users...)
|
|
}
|
|
return
|
|
}
|
|
|
|
// 推送私聊消息
|
|
func (this *Chat) pushChatToPrivate(msg *pb.DBChat) (err error) {
|
|
var (
|
|
session comm.IUserSession
|
|
ok bool
|
|
)
|
|
defer func() {
|
|
this.PutUserSession(session)
|
|
}()
|
|
if session, ok = this.GetUserSession(msg.Ruid); ok {
|
|
session.SendMsg(string(this.GetType()), "message", &pb.ChatMessagePush{Chat: msg})
|
|
if err = session.Push(); err != nil {
|
|
this.Errorf("err:%v", err)
|
|
}
|
|
|
|
} else {
|
|
err = this.modelChat.saveUserMsg(msg)
|
|
}
|
|
return
|
|
}
|
|
|
|
// 推送跨服频道消息
|
|
func (this *Chat) pushChatToCross(msg *pb.DBChat) (err error) {
|
|
var (
|
|
users []*pb.CacheUser
|
|
)
|
|
if users, err = this.modelChat.getCrossChannelMember(msg.ChannelId); err == nil {
|
|
if err = this.SendMsgToCUsers(string(this.GetType()), "message", &pb.ChatMessagePush{Chat: msg}, users...); err != nil {
|
|
this.Errorf("err:%v", err)
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// 推送系统消息
|
|
func (this *Chat) pushChatToSystem(msg *pb.DBChat) (err error) {
|
|
data, _ := anypb.New(&pb.ChatMessagePush{Chat: msg})
|
|
if err = this.service.ClusterBroadcast(context.Background(), comm.Service_Gateway, string(comm.Rpc_GatewaySendRadioMsg), pb.UserMessage{
|
|
MainType: string(this.GetType()),
|
|
SubType: "message",
|
|
Data: data,
|
|
}, nil); err != nil {
|
|
this.Errorf("err:%v", err)
|
|
}
|
|
return
|
|
}
|