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 *Manager) handleMsgServerClient(msc *libnet.Session) { msc.Process(func(msg *libnet.InBuffer) error { log.Info("msg_server", msc.Conn().RemoteAddr().String(), "say:", string(msg.Data)) self.parseProtocol(msg.Data, msc) 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 := 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 }
func (self *Gateway) 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 } self.msgServerNumMap[msc.Conn().RemoteAddr().String()] = c.SessionNum 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 }
/* Router -> MsgServer ROUTE_SEND_TOPIC_MSG_CMD arg0: ClientID //发送方用户ID arg1: ClientType //发送方终端类型,是client还是device arg2: Msg //消息内容 arg3: TopicName //群组名, device无须提供 */ func (self *ProtoProc) procSendMsgTopic(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procSendMsgTopic") var err error ms := session.Conn().RemoteAddr().String() //send2Msg := cmd.GetArgs()[0] topicName := cmd.GetArgs()[1] //fromID := cmd.GetArgs()[2] //fromType := cmd.GetArgs()[3] // check whether the topic exist topicCacheData, err := self.Router.topicCache.Get(topicName) if topicCacheData == nil { log.Warningf("TOPIC %s not exist: %s", topicName, err.Error()) return err } cmd.ChangeCmdName(protocol.ROUTE_SEND_TOPIC_MSG_CMD) log.Info(protocol.ROUTE_SEND_TOPIC_MSG_CMD) log.Info(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 != ms { // not in this server, routing it err = self.Router.msgServerClientMap[ip].Send(libnet.Json(cmd)) if err != nil { log.Error("error:", err) return err } } } } return nil }
func (self *ProtoProc) procLogin(cmd protocol.Cmd, session *libnet.Session) error { log.Info("procLogin") var err error ClientID := cmd.GetArgs()[0] uuid := cmd.GetArgs()[1] resp := protocol.NewCmdSimple(protocol.RSP_LOGIN_CMD) // for cache data sessionCacheData, err := self.msgServer.sessionCache.Get(ClientID) if err != nil { log.Warningf("no ID : %s", ClientID) } else if sessionCacheData.ID != uuid { log.Warningf("ID(%s) & uuid(%s) not matched", ClientID, uuid) err = common.NOT_LOGIN } if err == nil { resp.AddArg(protocol.RSP_SUCCESS) } else { resp.AddArg(protocol.RSP_ERROR) } err2 := session.Send(libnet.Json(resp)) if err2 != nil { log.Error(err2.Error()) return err2 } if err != nil { return err } // update the session cache sessionCacheData.ClientAddr = session.Conn().RemoteAddr().String() sessionCacheData.MsgServerAddr = self.msgServer.cfg.LocalIP sessionCacheData.Alive = true self.msgServer.sessionCache.Set(sessionCacheData) log.Info(sessionCacheData) self.msgServer.procOffline(ClientID) self.msgServer.procOnline(ClientID) /* 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[ClientID] = session self.msgServer.sessions[ClientID].State = base.NewSessionState(true, ClientID, sessionCacheData.ClientType) err = self.procOfflineMsg(session, ClientID) if err != nil { log.Error(err.Error()) return err } return nil }
func (self *MsgServer) 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) self.readMutex.Lock() defer self.readMutex.Unlock() log.Infof("[%s]->[%s]", session.Conn().RemoteAddr().String(), self.cfg.LocalIP) log.Info(c) switch c.GetCmdName() { case protocol.SEND_PING_CMD: err = pp.procPing(&c, session) if err != nil { log.Error("error:", err) return err } case protocol.SUBSCRIBE_CHANNEL_CMD: pp.procSubscribeChannel(&c, session) case protocol.REQ_LOGIN_CMD: err = pp.procLogin(&c, session) if err != nil { log.Error("error:", err) return err } case protocol.REQ_LOGOUT_CMD: err = pp.procLogout(&c, session) if err != nil { log.Error("error:", err) return err } case protocol.REQ_SEND_P2P_MSG_CMD: err = pp.procSendMessageP2P(&c, session) if err != nil { log.Error("error:", err) return err } case protocol.ROUTE_SEND_P2P_MSG_CMD: err = pp.procRouteMessageP2P(&c, session) if err != nil { log.Error("error:", err) return err } // p2p ack case protocol.IND_ACK_P2P_STATUS_CMD: err = pp.procP2pAck(&c, session) if err != nil { log.Error("error:", err) return err } // p2p ack case protocol.ROUTE_ACK_P2P_STATUS_CMD: err = pp.procP2pAck(&c, session) if err != nil { log.Error("error:", err) return err } case protocol.REQ_SEND_TOPIC_MSG_CMD: err = pp.procSendTopicMsg(&c, session) if err != nil { log.Error("error:", err) return err } case protocol.ROUTE_SEND_TOPIC_MSG_CMD: err = pp.procRouteTopicMsg(&c, session) if err != nil { log.Error("error:", err) return err } case protocol.REQ_CREATE_TOPIC_CMD: err = pp.procCreateTopic(&c, session) if err != nil { log.Error("error:", err) return err } case protocol.REQ_ADD_2_TOPIC_CMD: err = pp.procAdd2Topic(&c, session) if err != nil { log.Error("error:", err) return err } case protocol.REQ_KICK_TOPIC_CMD: err = pp.procKickTopic(&c, session) if err != nil { log.Error("error:", err) return err } case protocol.REQ_JOIN_TOPIC_CMD: err = pp.procJoinTopic(&c, session) if err != nil { log.Error("error:", err) return err } case protocol.REQ_QUIT_TOPIC_CMD: err = pp.procQuitTopic(&c, session) if err != nil { log.Error("error:", err) return err } case protocol.REQ_GET_TOPIC_LIST_CMD: err = pp.procGetTopicList(&c, session) if err != nil { log.Error("error:", err) return err } case protocol.REQ_GET_TOPIC_MEMBER_CMD: err = pp.procGetTopicMember(&c, session) if err != nil { log.Error("error:", err) return err } } return err }