func (self *MsgServer) procOffline(ID string) { // load all the topic list of this user if self.sessions[ID] != nil { self.sessions[ID].Close() delete(self.sessions, ID) sessionCacheData, err := self.sessionCache.Get(ID) if err != nil { log.Errorf("ID(%s) no session cache", ID) return } sessionCacheData.Alive = false self.sessionCache.Set(sessionCacheData) for _, topicName := range sessionCacheData.TopicList { topicCacheData, _ := self.topicCache.Get(topicName) if topicCacheData != nil { // update AliveMemberNumMap[server] if v, ok := topicCacheData.AliveMemberNumMap[self.cfg.LocalIP]; ok { if v > 0 { topicCacheData.AliveMemberNumMap[self.cfg.LocalIP] = v - 1 } else { topicCacheData.AliveMemberNumMap[self.cfg.LocalIP] = 0 } self.topicCache.Set(topicCacheData) } } } } }
func (self *MsgServer) procOnline(ID string) { // load all the topic list of this user sessionCacheData, err := self.sessionCache.Get(ID) if err != nil { log.Errorf("ID(%s) no session cache", ID) return } sessionCacheData.Alive = true self.sessionCache.Set(sessionCacheData) for _, topicName := range sessionCacheData.TopicList { topicCacheData, err := self.topicCache.Get(topicName) if err != nil { log.Error(err.Error()) return } if topicCacheData == nil { topicStoreData, err := self.mongoStore.GetTopicFromCid(topicName) if err != nil { log.Error(err.Error()) return } topicCacheData = redis_store.NewTopicCacheData(topicStoreData) } // update AliveMemberNumMap[server] if v, ok := topicCacheData.AliveMemberNumMap[self.cfg.LocalIP]; ok { topicCacheData.AliveMemberNumMap[self.cfg.LocalIP] = v + 1 } else { topicCacheData.AliveMemberNumMap[self.cfg.LocalIP] = 1 } self.topicCache.Set(topicCacheData) } }
/* device/client -> MsgServer -> Router REQ_SEND_TOPIC_MSG_CMD arg0: Msg //消息内容 arg1: TopicName //群组名, device无须提供 返回给消息发送者的消息 MsgServer -> device/client RSP_SEND_TOPIC_MSG_CMD arg0: SUCCESS/FAILED 通过Router转发消息(对终端开发者不可见) Router -> MsgServer ROUTE_SEND_TOPIC_MSG_CMD arg0: Msg //消息内容 arg1: TopicName //群组名 arg2: ClientID //发送方用户ID arg3: ClientType //发送方终端类型,是client还是device 发送给消息接受者的消息 MsgServer -> device/client REQ_SEND_TOPIC_MSG_CMD arg0: Msg //消息内容 arg1: TopicName //群组名 arg2: ClientID //发送方用户ID arg3: ClientType //发送方终端类型,是client还是device */ func (self *ProtoProc) procSendTopicMsg(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procSendTopicMsg") var err error var topicName string var topicCacheData *redis_store.TopicCacheData var sessionCacheData *redis_store.SessionCacheData //var sessionStoreData *mongo_store.SessionStoreData msg := cmd.GetArgs()[0] resp := protocol.NewCmdSimple(protocol.RSP_SEND_TOPIC_MSG_CMD) ClientID := session.State.(*base.SessionState).ClientID ClientType := session.State.(*base.SessionState).ClientType if ClientType == protocol.DEV_TYPE_CLIENT { if len(cmd.GetArgs()) != 2 { err = common.SYNTAX_ERROR goto ErrOut } } else if len(cmd.GetArgs()) != 1 { err = common.SYNTAX_ERROR goto ErrOut } // get session cache sessionCacheData, err = self.msgServer.sessionCache.Get(ClientID) if sessionCacheData == nil { log.Errorf("ID %s cache missing", ClientID) err = common.NOT_ONLINE goto ErrOut } else if ClientType == protocol.DEV_TYPE_WATCH { topicName = sessionCacheData.GetTopics()[0] } else { topicName = cmd.GetArgs()[1] } // check whether the topic exist topicCacheData, err = self.msgServer.topicCache.Get(topicName) if topicCacheData == nil { log.Warningf("TOPIC %s not exist", topicName) err = common.TOPIC_NOT_EXIST } else { topic_msg_resp := protocol.NewCmdSimple(cmd.GetCmdName()) topic_msg_resp.AddArg(msg) topic_msg_resp.AddArg(topicName) topic_msg_resp.AddArg(ClientID) topic_msg_resp.AddArg(ClientType) if topicCacheData.AliveMemberNumMap[self.msgServer.cfg.LocalIP] > 0 { // exactly in this server, just broadcasting log.Warningf("topic %s has %d member(s) in this server", topicName, topicCacheData.AliveMemberNumMap[self.msgServer.cfg.LocalIP]) for _, mID := range topicCacheData.MemberList { if self.msgServer.sessions[mID.ID] != nil { self.msgServer.sessions[mID.ID].Send(libnet.Json(topic_msg_resp)) if err != nil { log.Fatalln(err.Error()) } } } } if self.msgServer.channels[protocol.SYSCTRL_SEND] != nil { //topic_msg_resp.ChangeCmdName(protocol.ROUTE_SEND_TOPIC_MSG_CMD) for ip, num := range topicCacheData.AliveMemberNumMap { if num > 0 { log.Warningf("topic %s has %d member(s) in ip %s", topicName, num, ip) if ip != self.msgServer.cfg.LocalIP { // not in this server, routing it _, err = self.msgServer.channels[protocol.SYSCTRL_SEND].Channel.Broadcast(libnet.Json(topic_msg_resp)) if err != nil { log.Error(err.Error()) } break } } } } } ErrOut: if err != nil { resp.AddArg(err.Error()) } else { resp.AddArg(protocol.RSP_SUCCESS) } err = session.Send(libnet.Json(resp)) if err != nil { log.Error(err.Error()) } return err }