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 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 (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) } }
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 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/FishChatServer/monitor/views") beego.SetStaticPath("/views", "views") beego.Run() }
func (self *Manager) subscribeChannels() error { log.Info("subscribeChannels") var msgServerClientList []*libnet.Session 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_CLIENT_STATUS) cmd.AddArg(self.cfg.UUID) err = msgServerClient.Send(libnet.Json(cmd)) if err != nil { log.Error(err.Error()) return err } cmd = protocol.NewCmdSimple(protocol.SUBSCRIBE_CHANNEL_CMD) cmd.AddArg(protocol.SYSCTRL_TOPIC_STATUS) cmd.AddArg(self.cfg.UUID) err = msgServerClient.Send(libnet.Json(cmd)) if err != nil { log.Error(err.Error()) return err } cmd = protocol.NewCmdSimple(protocol.SUBSCRIBE_CHANNEL_CMD) cmd.AddArg(protocol.STORE_CLIENT_INFO) cmd.AddArg(self.cfg.UUID) err = msgServerClient.Send(libnet.Json(cmd)) if err != nil { log.Error(err.Error()) return err } cmd = protocol.NewCmdSimple(protocol.SUBSCRIBE_CHANNEL_CMD) cmd.AddArg(protocol.STORE_TOPIC_INFO) cmd.AddArg(self.cfg.UUID) err = msgServerClient.Send(libnet.Json(cmd)) if err != nil { log.Error(err.Error()) return err } msgServerClientList = append(msgServerClientList, msgServerClient) } for _, msc := range msgServerClientList { go self.handleMsgServerClient(msc) } return nil }
func (self *MsgServer) procJoinTopic(member *mongo_store.Member, topicName string) error { log.Info("procJoinTopic") var err error // check whether the topic exist topicCacheData, err := self.topicCache.Get(topicName) if topicCacheData == nil { log.Warningf("TOPIC %s not exist", topicName) return common.TOPIC_NOT_EXIST } if topicCacheData.MemberExist(member.ID) { log.Warningf("ClientID %s exists in topic %s", member.ID, topicName) return common.MEMBER_EXIST } sessionCacheData, err := self.sessionCache.Get(member.ID) if sessionCacheData == nil { log.Warningf("Client %s not online", member.ID) return common.NOT_ONLINE } // Watch can only be added in ONE topic //fmt.Println("len of topic list of %s: %d", member.ID, len(sessionCacheData.TopicList)) if member.Type == protocol.DEV_TYPE_WATCH && len(sessionCacheData.TopicList) >= 1 { log.Warningf("Watch %s is in topic %s", member.ID, sessionCacheData.TopicList[0]) return common.DENY_ACCESS } // session cache and store sessionCacheData.AddTopic(topicName) err = self.sessionCache.Set(sessionCacheData) if err != nil { log.Error(err.Error()) return err } err = self.mongoStore.Set(sessionCacheData.SessionStoreData) if err != nil { log.Error(err.Error()) return err } // topic cache and store topicCacheData.AddMember(member) err = self.topicCache.Set(topicCacheData) if err != nil { log.Error(err.Error()) return err } err = self.mongoStore.Set(topicCacheData.TopicStoreData) if err != nil { log.Error(err.Error()) return err } 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 }
/* 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 }
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 *RouterConfig) LoadConfig() error { file, err := os.Open(self.configfile) if err != nil { log.Error(err.Error()) return err } defer file.Close() dec := json.NewDecoder(file) err = dec.Decode(&self) if err != nil { log.Error(err.Error()) return err } return nil }
/* 发送给消息接受者的消息 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) procOfflineMsg(session *libnet.Session, ID string) error { var err error exist, err := self.msgServer.offlineMsgCache.IsKeyExist(ID) if exist.(int64) == 0 { return err } else { omrd, err := common.GetOfflineMsgFromOwnerName(self.msgServer.offlineMsgCache, ID) if err != nil { log.Error(err.Error()) return err } for _, v := range omrd.MsgList { if v.Msg == protocol.IND_ACK_P2P_STATUS_CMD { resp := protocol.NewCmdSimple(protocol.IND_ACK_P2P_STATUS_CMD) resp.AddArg(v.Uuid) resp.AddArg(v.FromID) // v.FromID is status if self.msgServer.sessions[ID] != nil { self.msgServer.sessions[ID].Send(libnet.Json(resp)) if err != nil { log.Error(err.Error()) return err } } } else { resp := protocol.NewCmdSimple(protocol.REQ_SEND_P2P_MSG_CMD) resp.AddArg(v.Msg) resp.AddArg(v.FromID) resp.AddArg(v.Uuid) if self.msgServer.sessions[ID] != nil { self.msgServer.sessions[ID].Send(libnet.Json(resp)) if err != nil { log.Error(err.Error()) return err } else { self.procP2PAckStatus(v.FromID, v.Uuid, protocol.P2P_ACK_SENT) } } } } omrd.ClearMsg() self.msgServer.offlineMsgCache.Set(omrd) } return err }
func (self *Manager) connectMsgServer(ms string) (*libnet.Session, error) { client, err := libnet.Dial("tcp", ms) if err != nil { log.Error(err.Error()) panic(err) } return client, err }
func StoreData(storeOp interface{}, data interface{}) error { switch data.(type) { case *redis_store.SessionCacheData: err := storeOp.(*redis_store.SessionCache).Set(data.(*redis_store.SessionCacheData)) //err := (*redis_store.SessionCache)(storeOp).Set(data) if err != nil { return err log.Error("error:", err) } log.Info("cache sesion success") return nil case *redis_store.TopicCacheData: err := storeOp.(*redis_store.TopicCache).Set(data.(*redis_store.TopicCacheData)) if err != nil { return err log.Error("error:", err) } log.Info("cache topic success") return nil case *mongo_store.SessionStoreData: err := storeOp.(*mongo_store.MongoStore).Set(data) if err != nil { return err log.Error("error:", err) } log.Info("store session success") return nil case *mongo_store.TopicStoreData: err := storeOp.(*mongo_store.MongoStore).Set(data) if err != nil { return err log.Error("error:", err) } log.Info("store topic success") return nil } return nil }
func handleSession(ms *MsgServer, session *libnet.Session) { session.Process(func(msg *libnet.InBuffer) error { err := ms.parseProtocol(msg.Data, session) if err != nil { log.Error(err.Error()) } return nil }) }
func handleSession(gw *Gateway, session *libnet.Session) { session.Process(func(msg *libnet.InBuffer) error { err := gw.parseProtocol(msg.Data, session) if err != nil { log.Error(err.Error()) } 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 */ 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 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 { member := mongo_store.NewMember(mID, mName, sessionCacheData.ClientType) err = self.msgServer.procJoinTopic(member, topicName) } } } 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 }
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 := 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) common.StoreData(self.gateway.sessionCache, 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 }
/* MsgServer -> Router REQ_SEND_P2P_MSG_CMD arg0: Sent2ID //接收方用户ID arg1: Msg //消息内容 arg2: FromID //发送方用户ID arg3: uuid //MsgServer分配的消息uuid */ func (self *ProtoProc) procSendMsgP2P(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procSendMsgP2P") var err error send2ID := cmd.GetArgs()[0] send2Msg := cmd.GetArgs()[1] log.Info(send2Msg) self.Router.readMutex.Lock() defer self.Router.readMutex.Unlock() cacheSession, err := self.Router.sessionCache.Get(send2ID) if cacheSession == nil || cacheSession.Alive == false { storeSession, err := self.Router.mongoStore.GetSessionFromCid(send2ID) if err != nil { log.Warningf("ID %s not registered, msg dropped", send2ID) return err } log.Info(storeSession) log.Warningf("ID registered but offline: %s", send2ID) cmd.ChangeCmdName(protocol.ROUTE_SEND_P2P_MSG_CMD) //ms := self.Router.cfg.MsgServerList[0] ms := session.Conn().RemoteAddr().String() err = self.Router.msgServerClientMap[ms].Send(libnet.Json(cmd)) if err != nil { log.Error("error:", err) return err } } else { log.Info(cacheSession.MsgServerAddr) cmd.ChangeCmdName(protocol.ROUTE_SEND_P2P_MSG_CMD) log.Info(cmd) err = self.Router.msgServerClientMap[cacheSession.MsgServerAddr].Send(libnet.Json(cmd)) if err != nil { log.Error("error:", err) return err } } return nil }
func (self *Gateway) parseProtocol(cmd []byte, session *libnet.Session) error { var c protocol.CmdSimple err := json.Unmarshal(cmd, &c) if err != nil { log.Error("error:", err) return err } pp := NewProtoProc(self) switch c.GetCmdName() { case protocol.REQ_LOGIN_CMD: err = pp.procLogin(&c, session) if err != nil { log.Error("error:", err) return err } } return err }
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) 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 }
/* client -> MsgServer REQ_KICK_TOPIC_CMD arg0: TopicName //群组名 arg1: NewClientID //待移除的成员用户ID MsgServer -> client RSP_KICK_TOPIC_CMD arg0: SUCCESS/FAILED */ func (self *ProtoProc) procKickTopic(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procKickTopic") var err error var topicCacheData *redis_store.TopicCacheData topicName := cmd.GetArgs()[0] mID := cmd.GetArgs()[1] ClientID := session.State.(*base.SessionState).ClientID ClientType := session.State.(*base.SessionState).ClientType resp := protocol.NewCmdSimple(protocol.RSP_KICK_TOPIC_CMD) if len(cmd.GetArgs()) != 2 { err = common.SYNTAX_ERROR goto ErrOut } // only DEV_TYPE_CLIENT CAN do this if ClientType != protocol.DEV_TYPE_CLIENT { err = common.DENY_ACCESS goto ErrOut } // 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 // 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 { err = self.msgServer.procQuitTopic(mID, topicName) } 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 }
func (self *Monitor) 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.CmdMonitor err := json.Unmarshal(msg.Data, &c) if err != nil { log.Error("error:", err) return err } return nil }) }
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 } 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, }) gw := NewGateway(cfg, rs) gw.subscribeChannels() 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 main() { version() fmt.Printf("built on %s\n", BuildTime()) flag.Parse() cfg := NewManagerConfig(*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()) } log.Info("server start:", server.Listener().Addr().String()) sm := NewManager(cfg) go sm.subscribeChannels() server.Serve(func(session *libnet.Session) { }) }
// not a good idea func (self *ProtoProc) procP2pAck(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procP2pAck") var err error if len(cmd.GetArgs()) != 3 { log.Error("procP2pAck: syntax error") return common.SYNTAX_ERROR } uuid := cmd.GetArgs()[0] status := cmd.GetArgs()[1] fromeID := cmd.GetArgs()[2] err = self.procP2PAckStatus(fromeID, uuid, status) return err }
func (self *MongoStore) GetTopicFromCid(cid string) (*TopicStoreData, error) { log.Info("MongoStore GetTopicFromCid") var err error self.rwMutex.Lock() defer self.rwMutex.Unlock() op := self.session.DB(DATA_BASE_NAME).C(TOPIC_INFO_COLLECTION) var result *TopicStoreData err = op.Find(bson.M{"TopicName": cid}).One(result) if err != nil { log.Error(err.Error()) return nil, err } return result, nil }
func (self *ProtoProc) procGetTopicMember(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procGetTopicMember") var err error var topicCacheData *redis_store.TopicCacheData resp := protocol.NewCmdSimple(protocol.RSP_GET_TOPIC_MEMBER_CMD) if len(cmd.GetArgs()) != 1 { err = common.SYNTAX_ERROR } else { topicName := cmd.GetArgs()[0] clientID := session.State.(*base.SessionState).ClientID //clientType := session.State.(*base.SessionState).ClientType // 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 if topicCacheData.MemberExist(clientID) == false { log.Warningf("%s not the member of topic %d", clientID, topicName) err = common.DENY_ACCESS } } if err != nil { resp.AddArg(err.Error()) } else { resp.AddArg(protocol.RSP_SUCCESS) resp.AddArg(strconv.Itoa(len(topicCacheData.MemberList))) for _, member := range topicCacheData.MemberList { resp.AddArg(member.ID) resp.AddArg(member.Name) } } err = session.Send(libnet.Json(resp)) if err != nil { log.Error(err.Error()) } return err }