package main import ( "strconv" "time" "github.com/globalsign/mgo/bson" "mongo.games.com/goserver/core/basic" "mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/module" "mongo.games.com/goserver/core/task" "mongo.games.com/game/model" ) var ChatMgrSington = &ChatMgr{ ChatList: make(map[string]map[string]*Chat), TsChat: make(map[int32]int64), } type ChatMgr struct { ChatList map[string]map[string]*Chat // platform:会话(snid,toSnid):聊天内容 TsChat map[int32]int64 // snid:时间戳 } type Chat struct { Id bson.ObjectId `bson:"_id"` BindSnid string //snid1 < snid2 ChatContent []*ChatContent LastChatTs int64 Dirty bool } type ChatContent struct { SrcSnId int32 Content string Ts int64 } func (this *ChatMgr) ModuleName() string { return "ChatMgr" } func (this *ChatMgr) Init() { } // CanSendToPlatform 大厅聊天cd(5秒) func (this *ChatMgr) CanSendToPlatform(snid int32) bool { if this.TsChat[snid] == 0 { this.TsChat[snid] = time.Now().Unix() return true } if time.Now().Unix()-this.TsChat[snid] > 5 { this.TsChat[snid] = time.Now().Unix() return true } return false } func (this *ChatMgr) getBindSnid(snid, tosnid int32) string { ret := "" if snid <= tosnid { ret = strconv.FormatInt(int64(snid), 10) + "_" + strconv.FormatInt(int64(tosnid), 10) } else { ret = strconv.FormatInt(int64(tosnid), 10) + "_" + strconv.FormatInt(int64(snid), 10) } return ret } // 新增聊天信息 func (this *ChatMgr) AddChat(platform string, snid, tosnid int32, content string) { bindSnid := this.getBindSnid(snid, tosnid) logger.Logger.Trace("(this *ChatMgr) AddChat ", bindSnid) if this.ChatList[platform] == nil { this.ChatList[platform] = make(map[string]*Chat) } var cl *Chat if _, exist := this.ChatList[platform][bindSnid]; !exist { cacheCl := this.db2cache(model.NewChat(bindSnid)) cl = &cacheCl this.ChatList[platform][bindSnid] = cl } cl = this.ChatList[platform][bindSnid] cc := &ChatContent{ SrcSnId: snid, Content: content, Ts: time.Now().Unix(), } cl.ChatContent = append(cl.ChatContent, cc) cl.LastChatTs = time.Now().Unix() cl.Dirty = true } // 删除聊天信息 func (this *ChatMgr) DelChat(platform string, snid, tosnid int32) { bindSnid := this.getBindSnid(snid, tosnid) logger.Logger.Trace("(this *ChatMgr) DelChat ", bindSnid) if this.ChatList[platform] == nil { return } if _, exist := this.ChatList[platform][bindSnid]; exist { delete(this.ChatList[platform], bindSnid) task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { model.DelChat(platform, bindSnid) return nil }), nil).StartByFixExecutor("DelChat") } } // 聊天信息 func (this *ChatMgr) SetChat(platform string, bindSnid string, chat *model.Chat) { logger.Logger.Trace("(this *ChatMgr) SetChat ", bindSnid) if this.ChatList[platform] == nil { this.ChatList[platform] = make(map[string]*Chat) } if _, exist := this.ChatList[platform][bindSnid]; !exist { cacheChat := this.db2cache(chat) this.ChatList[platform][bindSnid] = &cacheChat } } // 获取聊天信息 func (this *ChatMgr) GetChat(platform string, snid, tosnid int32) *Chat { bindSnid := this.getBindSnid(snid, tosnid) logger.Logger.Trace("(this *ChatMgr) GetChat ", bindSnid) if this.ChatList[platform] == nil { return nil } return this.ChatList[platform][bindSnid] } func (this *ChatMgr) SaveChatData(platform string, snid, tosnid int32) { bindSnid := this.getBindSnid(snid, tosnid) logger.Logger.Trace("(this *ChatMgr) SaveChatData ", bindSnid) if this.ChatList[platform] == nil { return } if chat, exist := this.ChatList[platform][bindSnid]; exist { if chat != nil && chat.Dirty { chat.Dirty = false dbchat := this.cache2db(chat) task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { return model.UpsertChat(platform, bindSnid, &dbchat) }), nil, "SaveChatData").StartByFixExecutor("SnId:" + strconv.Itoa(int(snid))) } } } // db -> cache func (this *ChatMgr) db2cache(chat *model.Chat) (c Chat) { if chat != nil { c.Id = chat.Id c.BindSnid = chat.BindSnid if chat.ChatContent != nil { for _, content := range chat.ChatContent { cc := &ChatContent{ SrcSnId: content.SrcSnId, Content: content.Content, Ts: content.Ts, } c.ChatContent = append(c.ChatContent, cc) } } c.LastChatTs = chat.LastChatTs } return c } // cache -> db func (this *ChatMgr) cache2db(chat *Chat) (c model.Chat) { if chat != nil { c.Id = chat.Id c.BindSnid = chat.BindSnid if chat.ChatContent != nil { for _, content := range chat.ChatContent { cc := &model.ChatContent{ SrcSnId: content.SrcSnId, Content: content.Content, Ts: content.Ts, } c.ChatContent = append(c.ChatContent, cc) } } c.LastChatTs = chat.LastChatTs } return c } func (this *ChatMgr) Update() { } func (this *ChatMgr) Shutdown() { for platform, chatList := range this.ChatList { for bindSnid, chat := range chatList { dbchat := this.cache2db(chat) model.UpsertChat(platform, bindSnid, &dbchat) } } module.UnregisteModule(this) } func init() { module.RegisteModule(ChatMgrSington, time.Second, 0) }