func main() { version() fmt.Printf("built on %s\n", BuildTime()) flag.Parse() cfg := NewGatewayConfig(*InputConfFile) err := cfg.LoadConfig() if err != nil { log.Error(err.Error()) return } gw := NewGateway(cfg) gw.server, err = libnet.Listen(cfg.TransportProtocols, cfg.Listen) if err != nil { log.Error(err.Error()) return } log.Info("gateway server running at ", gw.server.Listener().Addr().String()) gw.server.Serve(func(session *libnet.Session) { log.Info("client ", session.Conn().RemoteAddr().String(), " | come in") go handleSession(gw, session) }) }
func (self *ProtoProc) procSendMessageTopic(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procSendMessageTopic") var err error topicName := cmd.GetArgs()[0] send2Msg := cmd.GetArgs()[1] log.Info(send2Msg) log.Info(topicName) if self.msgServer.topics[topicName] == nil { log.Warning(topicName + " is not exist") } else { resp := protocol.NewCmdSimple(protocol.RESP_MESSAGE_TOPIC_CMD) resp.AddArg(topicName) resp.AddArg(send2Msg) resp.AddArg(session.State.(*base.SessionState).ClientID) _, err = self.msgServer.topics[topicName].Channel.Broadcast(libnet.Json(resp)) if err != nil { log.Error(err.Error()) return err } } return err }
func (self *MongoStore) Set(data interface{}) error { log.Info("MongoStore Update") var err error self.rwMutex.Lock() defer self.rwMutex.Unlock() switch data.(type) { case *SessionStoreData: op := self.session.DB(DATA_BASE_NAME).C(CLIENT_INFO_COLLECTION) cid := data.(*SessionStoreData).ClientID log.Info("cid : ", cid) _, err = op.Upsert(bson.M{"ClientID": cid}, data.(*SessionStoreData)) if err != nil { log.Error(err.Error()) return err } case *TopicStoreData: op := self.session.DB(DATA_BASE_NAME).C(TOPIC_INFO_COLLECTION) topicName := data.(*TopicStoreData).TopicName log.Info("topicName : ", topicName) _, err = op.Upsert(bson.M{"TopicName": topicName}, data.(*TopicStoreData)) if err != nil { log.Error(err.Error()) return err } } return err }
func (self *MongoStore) Update(db string, c string, data interface{}) error { log.Info("MongoStore Update") var err error self.rwMutex.Lock() defer self.rwMutex.Unlock() op := self.session.DB(db).C(c) switch data.(type) { case *SessionStoreData: cid := data.(*SessionStoreData).ClientID log.Info("cid : ", cid) _, err = op.Upsert(bson.M{"ClientID": cid}, data.(*SessionStoreData)) if err != nil { log.Error(err.Error()) return err } case *TopicStoreData: topicName := data.(*TopicStoreData).TopicName log.Info("topicName : ", topicName) _, err = op.Upsert(bson.M{"TopicName": topicName}, data.(*TopicStoreData)) if err != nil { log.Error(err.Error()) return err } } return err }
func (self *MsgServer) scanDeadSession() { log.Info("scanDeadSession") timer := time.NewTicker(self.cfg.ScanDeadSessionTimeout * time.Second) ttl := time.After(self.cfg.Expire * time.Second) for { select { case <-timer.C: log.Info("scanDeadSession timeout") go func() { for id, s := range self.sessions { self.scanSessionMutex.Lock() //defer self.scanSessionMutex.Unlock() if (s.State).(*base.SessionState).Alive == false { log.Info("delete" + id) delete(self.sessions, id) } else { s.State.(*base.SessionState).Alive = false } self.scanSessionMutex.Unlock() } }() case <-ttl: break } } }
func (self *ProtoProc) procCreateTopic(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procCreateTopic") var err error if len(cmd.GetArgs()) != 1 { return CMD_NOT_CORRECT } topicName := cmd.GetArgs()[0] topicCacheData := redis_store.NewTopicCacheData(topicName, session.State.(*base.SessionState).ClientID, self.msgServer.cfg.LocalIP) t := protocol.NewTopic(topicName, self.msgServer.cfg.LocalIP, session.State.(*base.SessionState).ClientID, session) t.ClientIDList = append(t.ClientIDList, session.State.(*base.SessionState).ClientID) t.TSD = topicCacheData self.msgServer.topics[topicName] = t self.msgServer.topics[topicName].Channel = libnet.NewChannel(self.msgServer.server.Protocol()) self.msgServer.topics[topicName].Channel.Join(session, nil) log.Info(topicCacheData) args := make([]string, 0) args = append(args, topicName) CCmd := protocol.NewCmdInternal(protocol.CACHE_TOPIC_CMD, args, topicCacheData) m := redis_store.NewMember(session.State.(*base.SessionState).ClientID) CCmd.AnyData.(*redis_store.TopicCacheData).MemberList = append(CCmd.AnyData.(*redis_store.TopicCacheData).MemberList, m) log.Info(CCmd) if self.msgServer.channels[protocol.SYSCTRL_TOPIC_STATUS] != nil { _, err = self.msgServer.channels[protocol.SYSCTRL_TOPIC_STATUS].Channel.Broadcast(libnet.Json(CCmd)) if err != nil { log.Error(err.Error()) return err } } // store topic topicStoreData := mongo_store.NewTopicStoreData(topicName, session.State.(*base.SessionState).ClientID, self.msgServer.cfg.LocalIP) args = make([]string, 0) args = append(args, topicName) CCmd = protocol.NewCmdInternal(protocol.STORE_TOPIC_CMD, args, topicStoreData) member := mongo_store.NewMember(session.State.(*base.SessionState).ClientID) CCmd.AnyData.(*mongo_store.TopicStoreData).MemberList = append(CCmd.AnyData.(*mongo_store.TopicStoreData).MemberList, member) log.Info(CCmd) if self.msgServer.channels[protocol.STORE_TOPIC_INFO] != nil { _, err = self.msgServer.channels[protocol.STORE_TOPIC_INFO].Channel.Broadcast(libnet.Json(CCmd)) if err != nil { log.Error(err.Error()) return err } } return nil }
func (self *ProtoProc) procLogin(cmd protocol.Cmd, session *libnet.Session) error { //log.Info("procLogin") var err error var uuid string var msgServer string ClientID := cmd.GetArgs()[0] ClientType := cmd.GetArgs()[1] ClientPwd := "" if len(cmd.GetArgs()) == 3 { ClientPwd = cmd.GetArgs()[2] } // get the session cache sessionCacheData, err := self.gateway.sessionCache.Get(ClientID) if sessionCacheData != nil { log.Warningf("ID %s already login", ClientID) msgServer = sessionCacheData.MsgServerAddr uuid = sessionCacheData.ID } else { // choose msg server and allocate UUID msgServer = self.procGetMinLoadMsgServer() uuid = common.NewV4().String() // get the session store to check whether registered sessionStoreData, _ := self.gateway.mongoStore.GetSessionFromCid(ClientID) if sessionStoreData == nil { log.Warningf("ID %s not registered", ClientID) // for store data sessionStoreData = mongo_store.NewSessionStoreData(ClientID, ClientPwd, ClientType) log.Info(sessionStoreData) common.StoreData(self.gateway.mongoStore, sessionStoreData) } // for cache data, MsgServer MUST update local & remote addr. sessionCacheData = redis_store.NewSessionCacheData(sessionStoreData, session.Conn().RemoteAddr().String(), msgServer, uuid) log.Info(sessionCacheData) self.gateway.sessionCache.Set(sessionCacheData) } // resp := protocol.NewCmdSimple(protocol.RSP_LOGIN_CMD) resp.AddArg(protocol.RSP_SUCCESS) resp.AddArg(uuid) resp.AddArg(msgServer) log.Info("Resp | ", resp) if session != nil { err = session.Send(libnet.Json(resp)) if err != nil { log.Error(err.Error()) } session.Close() log.Info("client ", session.Conn().RemoteAddr().String(), " | close") } return nil }
func (self *ProtoProc) procStoreSession(data interface{}, session *libnet.Session) error { log.Info("procStoreSession") var err error log.Info(data) err = self.Manager.mongoStore.Update(mongo_store.DATA_BASE_NAME, mongo_store.CLIENT_INFO_COLLECTION, data) if err != nil { return err log.Error("error:", err) } return nil }
func (self *ProtoProc) procStoreSession(data interface{}, session *libnet.Session) error { log.Info("procStoreSession") var err error log.Info(data) err = self.Manager.mongoStore.Set(data.(*mongo_store.SessionStoreData)) if err != nil { return err log.Error("error:", err) } return nil }
func (self *ProtoProc) procClientID(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procClientID") var err error ID := cmd.GetArgs()[0] // for cache data sessionCacheData := redis_store.NewSessionCacheData(cmd.GetArgs()[0], session.Conn().RemoteAddr().String(), self.msgServer.cfg.LocalIP, strconv.FormatUint(session.Id(), 10)) log.Info(sessionCacheData) args := make([]string, 0) args = append(args, cmd.GetArgs()[0]) CCmd := protocol.NewCmdInternal(protocol.CACHE_SESSION_CMD, args, sessionCacheData) log.Info(CCmd) if self.msgServer.channels[protocol.SYSCTRL_CLIENT_STATUS] != nil { _, err = self.msgServer.channels[protocol.SYSCTRL_CLIENT_STATUS].Channel.Broadcast(libnet.Json(CCmd)) if err != nil { log.Error(err.Error()) return err } } // for store data sessionStoreData := mongo_store.SessionStoreData{ID, session.Conn().RemoteAddr().String(), self.msgServer.cfg.LocalIP, true} log.Info(sessionStoreData) args = make([]string, 0) args = append(args, cmd.GetArgs()[0]) CCmd = protocol.NewCmdInternal(protocol.STORE_SESSION_CMD, args, sessionStoreData) log.Info(CCmd) if self.msgServer.channels[protocol.STORE_CLIENT_INFO] != nil { _, err = self.msgServer.channels[protocol.STORE_CLIENT_INFO].Channel.Broadcast(libnet.Json(CCmd)) if err != nil { log.Error(err.Error()) return err } } self.msgServer.sessions[cmd.GetArgs()[0]] = session self.msgServer.sessions[cmd.GetArgs()[0]].State = base.NewSessionState(true, cmd.GetArgs()[0]) err = self.procOfflineMsg(session, ID) if err != nil { log.Error(err.Error()) return err } return nil }
func (self *ProtoProc) procCacheTopic(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procCacheTopic") var err error log.Info(cmd.GetAnyData()) err = self.Manager.topicCache.Set(cmd.GetAnyData().(*redis_store.TopicCacheData)) if err != nil { return err log.Error("error:", err) } log.Info("set sesion id success") return nil }
func (self *ProtoProc) procSubscribeChannel(cmd protocol.Cmd, session *libnet.Session) { log.Info("procSubscribeChannel") channelName := cmd.GetArgs()[0] cUUID := cmd.GetArgs()[1] log.Info(channelName) if self.msgServer.channels[channelName] != nil { self.msgServer.channels[channelName].Channel.Join(session, nil) self.msgServer.channels[channelName].ClientIDlist = append(self.msgServer.channels[channelName].ClientIDlist, cUUID) } else { log.Warning(channelName + " is not exist") } log.Info(self.msgServer.channels) }
func (self *Monitor) subscribeChannels() error { log.Info("monitor start to subscribeChannels") for _, ms := range self.cfg.MsgServerList { msgServerClient, err := self.connectMsgServer(ms) if err != nil { log.Error(err.Error()) return err } cmd := protocol.NewCmdSimple(protocol.SUBSCRIBE_CHANNEL_CMD) cmd.AddArg(protocol.SYSCTRL_MONITOR) cmd.AddArg(self.cfg.UUID) err = msgServerClient.Send(libnet.Json(cmd)) if err != nil { log.Error(err.Error()) return err } self.msgServerClientMap[ms] = msgServerClient } for _, msc := range self.msgServerClientMap { go self.handleMsgServerClient(msc) } return nil }
func (self *MsgServer) createChannels() { log.Info("createChannels") for _, c := range base.ChannleList { channel := libnet.NewChannel(self.server.Protocol()) self.channels[c] = base.NewChannelState(c, channel) } }
func (self *MsgServer) sendMonitorData() error { log.Info("sendMonitorData") resp := protocol.NewCmdMonitor() // resp.SessionNum = (uint64)(len(self.sessions)) // log.Info(resp) mb := NewMonitorBeat("monitor", self.cfg.MonitorBeatTime, 40, 10) if self.channels[protocol.SYSCTRL_MONITOR] != nil { for { resp.SessionNum = (uint64)(len(self.sessions)) //log.Info(resp) mb.Beat(self.channels[protocol.SYSCTRL_MONITOR].Channel, resp) } // _, err := self.channels[protocol.SYSCTRL_MONITOR].Channel.Broadcast(libnet.Json(resp)) // if err != nil { // glog.Error(err.Error()) // return err // } } return nil }
func GetTopicFromTopicName(storeOp interface{}, topicName string) (*redis_store.TopicCacheData, error) { switch storeOp.(type) { case *redis_store.TopicCache: topic, err := storeOp.(*redis_store.TopicCache).Get(topicName) if err != nil { log.Warningf("no topicName : %s", topicName) return nil, err } if topic != nil { log.Info(topic) } return topic, nil } return nil, NOTFOUNT // topic ,err := topicCache.Get(topicName) // if err != nil { // log.Warningf("no topicName : %s", topicName) // return nil, err // } // if topic != nil { // log.Info(topic) // } // return topic, nil }
func GetSessionFromCID(storeOp interface{}, ID string) (*redis_store.SessionCacheData, error) { switch storeOp.(type) { case *redis_store.SessionCache: session, err := storeOp.(*redis_store.SessionCache).Get(ID) if err != nil { log.Warningf("no ID : %s", ID) return nil, err } if session != nil { log.Info(session) } return session, nil } return nil, NOTFOUNT // session ,err := sessionCache.Get(ID) // if err != nil { // log.Warningf("no ID : %s", ID) // return nil, err // } // if session != nil { // log.Info(session) // } // return session, nil }
func main() { version() fmt.Printf("built on %s\n", BuildTime()) flag.Parse() cfg := NewRouterConfig(*InputConfFile) err := cfg.LoadConfig() if err != nil { log.Error(err.Error()) return } server, err := libnet.Listen(cfg.TransportProtocols, cfg.Listen) if err != nil { log.Error(err.Error()) return } log.Info("server start: ", server.Listener().Addr().String()) rs := redis_store.NewRedisStore(&redis_store.RedisStoreOptions{ Network: "tcp", Address: cfg.Redis.Addr + cfg.Redis.Port, ConnectTimeout: time.Duration(cfg.Redis.ConnectTimeout) * time.Millisecond, ReadTimeout: time.Duration(cfg.Redis.ReadTimeout) * time.Millisecond, WriteTimeout: time.Duration(cfg.Redis.WriteTimeout) * time.Millisecond, Database: 1, KeyPrefix: base.COMM_PREFIX, }) r := NewRouter(cfg, rs) //TODO not use go go r.subscribeChannels() server.Serve(func(session *libnet.Session) { }) }
func main() { version() fmt.Printf("built on %s\n", BuildTime()) flag.Parse() cfg := NewRouterConfig(*InputConfFile) err := cfg.LoadConfig() if err != nil { log.Error(err.Error()) return } server, err := libnet.Listen(cfg.TransportProtocols, cfg.Listen) if err != nil { log.Error(err.Error()) return } log.Info("server start: ", server.Listener().Addr().String()) r := NewRouter(cfg) //TODO not use go go r.subscribeChannels() server.Serve(func(session *libnet.Session) { }) }
func (self *Router) handleMsgServerClient(msc *libnet.Session) { msc.Process(func(msg *libnet.InBuffer) error { log.Info("msg_server", msc.Conn().RemoteAddr().String(), " say: ", string(msg.Data)) var c protocol.CmdInternal pp := NewProtoProc(self) err := json.Unmarshal(msg.Data, &c) if err != nil { log.Error("error:", err) return err } switch c.GetCmdName() { case protocol.REQ_SEND_P2P_MSG_CMD: err := pp.procSendMsgP2P(&c, msc) if err != nil { log.Warning(err.Error()) } case protocol.IND_ACK_P2P_STATUS_CMD: err := pp.procAckP2pStatus(&c, msc) if err != nil { log.Warning(err.Error()) } case protocol.REQ_SEND_TOPIC_MSG_CMD: err := pp.procSendMsgTopic(&c, msc) if err != nil { log.Warning(err.Error()) } } return nil }) }
func (self *ProtoProc) procGetTopicList(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procGetTopicList") var err error resp := protocol.NewCmdSimple(protocol.RSP_GET_TOPIC_LIST_CMD) clientID := session.State.(*base.SessionState).ClientID //clientType := session.State.(*base.SessionState).ClientType sessionCacheData, err := self.msgServer.sessionCache.Get(clientID) if sessionCacheData == nil { log.Warningf("Client %s not online", clientID) err = common.NOT_ONLINE goto ErrOut } ErrOut: if err != nil { resp.AddArg(err.Error()) } else { resp.AddArg(protocol.RSP_SUCCESS) resp.AddArg(strconv.Itoa(len(sessionCacheData.TopicList))) for _, topic := range sessionCacheData.TopicList { resp.AddArg(topic) } } err = session.Send(libnet.Json(resp)) if err != nil { log.Error(err.Error()) } return err }
func main() { version() fmt.Printf("built on %s\n", BuildTime()) flag.Parse() cfg := NewMonitorConfig(*InputConfFile) err := cfg.LoadConfig() if err != nil { log.Error(err.Error()) return } server, err := libnet.Listen(cfg.TransportProtocols, cfg.Listen) if err != nil { log.Error(err.Error()) return } log.Info("server start: ", server.Listener().Addr().String()) m := NewMonitor(cfg) //TODO not use go m.subscribeChannels() go server.Serve(func(session *libnet.Session) { }) beego.Router("api/v1/monitor", &controllers.MonitorController{}) //beego.SetStaticPath("/views", "/mh/mygo/src/github.com/oikomi/FishChatServer/monitor/views") beego.SetStaticPath("/views", "views") beego.Run() }
func GetOfflineMsgFromOwnerName(storeOp interface{}, ownerName string) (*redis_store.OfflineMsgCacheData, error) { switch storeOp.(type) { case *redis_store.OfflineMsgCache: o, err := storeOp.(*redis_store.OfflineMsgCache).Get(ownerName) if err != nil { log.Warningf("no ownerName : %s", ownerName) return nil, err } if o != nil { log.Info(o) } return o, nil } return nil, NOTFOUNT // o ,err := offlineMsgCache.Get(ownerName) // if err != nil { // log.Warningf("no ownerName : %s", ownerName) // return nil, err // } // if o != nil { // log.Info(o) // } // return o, nil }
/* 通过Router转发消息(对终端开发者不可见) Router -> MsgServer ROUTE_SEND_TOPIC_MSG_CMD arg0: Msg //消息内容 arg1: TopicName //群组名 arg2: ClientID //发送方用户ID arg3: ClientType //发送方终端类型,是client还是device */ func (self *ProtoProc) procRouteTopicMsg(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procRouteTopicMsg") var err error //send2Msg := cmd.GetArgs()[0] topicName := cmd.GetArgs()[1] //fromID := cmd.GetArgs()[2] //fromType := cmd.GetArgs()[3] // check whether the topic exist topicCacheData, err := self.msgServer.topicCache.Get(topicName) if topicCacheData == nil { log.Warningf("TOPIC %s not exist: %s", topicName, err.Error()) return common.TOPIC_NOT_EXIST } cmd.ChangeCmdName(protocol.IND_SEND_TOPIC_MSG_CMD) // 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(cmd)) if err != nil { log.Fatalln(err.Error()) } } } return nil }
func (self *ProtoProc) procRouteMessageP2P(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procRouteMessageP2P") var err error send2ID := cmd.GetArgs()[0] send2Msg := cmd.GetArgs()[1] fromID := cmd.GetArgs()[2] uuid := cmd.GetArgs()[3] _, err = common.GetSessionFromCID(self.msgServer.sessionCache, send2ID) if err != nil { log.Warningf("no ID : %s", send2ID) return err } resp := protocol.NewCmdSimple(protocol.RESP_MESSAGE_P2P_CMD) resp.AddArg(send2Msg) resp.AddArg(fromID) // add uuid resp.AddArg(uuid) if self.msgServer.sessions[send2ID] != nil { self.msgServer.sessions[send2ID].Send(libnet.Json(resp)) if err != nil { log.Fatalln(err.Error()) } } return nil }
/* client -> MsgServer REQ_QUIT_TOPIC_CMD arg0: TopicName //群组名 MsgServer -> client RSP_QUIT_TOPIC_CMD arg0: SUCCESS/ERROR */ func (self *ProtoProc) procQuitTopic(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procQuitTopic") var err error if len(cmd.GetArgs()) != 1 { err = common.SYNTAX_ERROR } else { topicName := cmd.GetArgs()[0] clientID := session.State.(*base.SessionState).ClientID err = self.msgServer.procQuitTopic(clientID, topicName) } resp := protocol.NewCmdSimple(protocol.RSP_QUIT_TOPIC_CMD) 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 }
/* client -> MsgServer REQ_JOIN_TOPIC_CMD arg0: TopicName //群组名 arg1: ClientName //用户在Topic中的Name, 比如老爸/老妈 MsgServer -> client RSP_JOIN_TOPIC_CMD arg0: SUCCESS/FAILED */ func (self *ProtoProc) procJoinTopic(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procJoinTopic") var err error if len(cmd.GetArgs()) != 2 { err = common.SYNTAX_ERROR } else { topicName := cmd.GetArgs()[0] clientName := cmd.GetArgs()[1] clientID := session.State.(*base.SessionState).ClientID clientType := session.State.(*base.SessionState).ClientType member := mongo_store.NewMember(clientID, clientName, clientType) err = self.msgServer.procJoinTopic(member, topicName) } resp := protocol.NewCmdSimple(protocol.RSP_JOIN_TOPIC_CMD) 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 }
/* Router -> MsgServer ROUTE_SEND_P2P_MSG_CMD arg0: Sent2ID //接收方用户ID arg1: Msg //消息内容 arg2: FromID //发送方用户ID arg3: uuid //MsgServer分配的消息uuid 发送给消息接受者的消息 MsgServer -> device/client REQ_SEND_P2P_MSG_CMD arg0: Msg //消息内容 arg1: FromID //发送方用户ID arg2: uuid //MsgServer分配的消息uuid,可选,如果提供了则须IND_ACK_P2P_STATUS_CMD(ClientID, uuid) */ func (self *ProtoProc) procRouteMessageP2P(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procRouteMessageP2P") var err error send2ID := cmd.GetArgs()[0] send2Msg := cmd.GetArgs()[1] fromID := cmd.GetArgs()[2] uuid := cmd.GetArgs()[3] if self.msgServer.sessions[send2ID] != nil { resp := protocol.NewCmdSimple(protocol.IND_SEND_P2P_MSG_CMD) resp.AddArg(send2Msg) resp.AddArg(fromID) // add uuid resp.AddArg(uuid) err = self.msgServer.sessions[send2ID].Send(libnet.Json(resp)) if err != nil { log.Fatalln(err.Error()) } else { self.procP2PAckStatus(fromID, uuid, protocol.P2P_ACK_SENT) } } return nil }
/* client -> MsgServer REQ_ADD_2_TOPIC_CMD arg0: TopicName //群组名 arg1: NewClientID //用户ID arg2: NewClientName //用户在Topic中的Name, 对于device, 可以是儿子/女儿 MsgServer -> client RSP_ADD_2_TOPIC_CMD arg0: SUCCESS/FAILED arg1: TopicName arg2: ClientID arg3: ClientType */ func (self *ProtoProc) procAdd2Topic(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procAdd2Topic") var err error topicName := cmd.GetArgs()[0] mID := cmd.GetArgs()[1] mName := cmd.GetArgs()[2] ClientID := session.State.(*base.SessionState).ClientID ClientType := session.State.(*base.SessionState).ClientType mType := protocol.DEV_TYPE_CLIENT resp := protocol.NewCmdSimple(protocol.RSP_ADD_2_TOPIC_CMD) if len(cmd.GetArgs()) != 3 { err = common.SYNTAX_ERROR } else // only DEV_TYPE_CLIENT CAN create topic if ClientType != protocol.DEV_TYPE_CLIENT { err = common.DENY_ACCESS } else { // check whether the topic exist topicCacheData, _ := self.msgServer.topicCache.Get(topicName) if topicCacheData == nil { log.Infof("TOPIC %s not exist in CACHE", topicName) err = common.TOPIC_NOT_EXIST } else // only topic creater can do this if topicCacheData.CreaterID != ClientID { log.Warningf("ClientID %s is not creater of topic %s", ClientID, topicName) err = common.DENY_ACCESS } else { // New Member MUST be online sessionCacheData, _ := self.msgServer.sessionCache.Get(mID) if sessionCacheData == nil { log.Warningf("Client %s not online", mID) err = common.NOT_ONLINE } else { mType = sessionCacheData.ClientType member := mongo_store.NewMember(mID, mName, mType) err = self.msgServer.procJoinTopic(member, topicName) } } } if err != nil { resp.AddArg(err.Error()) } else { resp.AddArg(protocol.RSP_SUCCESS) } resp.AddArg(topicName) resp.AddArg(mID) resp.AddArg(mType) err = session.Send(libnet.Json(resp)) if err != nil { log.Error(err.Error()) } return err }
//Note: router do not process topic func (self *ProtoProc) procSendMsgTopic(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procSendMsgTopic") //var err error //topicName := string(cmd.Args[0]) //send2Msg := string(cmd.Args[1]) return nil }