Beispiel #1
0
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 *ProtoProc) procSendMessageTopic(cmd protocol.Cmd, session *libnet.Session) error {
	glog.Info("procSendMessageTopic")
	var err error
	topicName := cmd.GetArgs()[0]
	send2Msg := cmd.GetArgs()[1]
	glog.Info(send2Msg)
	glog.Info(topicName)

	if self.msgServer.topics[topicName] == nil {
		glog.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 {
			glog.Error(err.Error())
			return err
		}
	}

	return err
}
func (self *ProtoProc) procOfflineMsg(session *libnet.Session, ID string) error {
	var err error
	exist, err := self.msgServer.offlineMsgStore.IsKeyExist(ID)
	if exist.(int64) == 0 {
		return err
	} else {
		omrd, err := common.GetOfflineMsgFromOwnerName(self.msgServer.offlineMsgStore, ID)
		if err != nil {
			glog.Error(err.Error())
			return err
		}
		for _, v := range omrd.MsgList {
			resp := protocol.NewCmdSimple(protocol.RESP_MESSAGE_P2P_CMD)
			resp.AddArg(v.Msg)
			resp.AddArg(v.FromID)

			if self.msgServer.sessions[ID] != nil {
				self.msgServer.sessions[ID].Send(libnet.Json(resp))
				if err != nil {
					glog.Error(err.Error())
					return err
				}
			}
		}

		omrd.ClearMsg()
		self.msgServer.offlineMsgStore.Set(omrd)
	}

	return err
}
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
}
Beispiel #5
0
/*
   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
}
Beispiel #6
0
/*
   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
}
Beispiel #7
0
/*
   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
}
Beispiel #8
0
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
}
Beispiel #9
0
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
}
Beispiel #10
0
/*
   发送给消息接受者的消息
   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.IND_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
}
Beispiel #11
0
/*
   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
}
Beispiel #12
0
func cmd_logout(self *Client, args []string) error {
	if self.bLogin == true {
		cmd := protocol.NewCmdSimple(protocol.REQ_LOGOUT_CMD)
		err := self.session.Send(libnet.Json(cmd))
		self.bLogin = false
		return err
	}
	return nil
}
Beispiel #13
0
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
}
Beispiel #14
0
/*
   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
}
Beispiel #15
0
func cmd_quit(self *Client, args []string) error {
	if self.bLogin == false {
		fmt.Println("NOT login yet. Please login first.")
		return nil
	}
	if len(args) != 2 {
		return common.SYNTAX_ERROR
	}
	cmd := protocol.NewCmdSimple(protocol.REQ_QUIT_TOPIC_CMD)
	cmd.AddArg(args[1])

	err := self.session.Send(libnet.Json(cmd))
	return err
}
Beispiel #16
0
func cmd_topic(self *Client, args []string) error {
	// get topic list
	if self.bLogin == false {
		fmt.Println("NOT login yet. Please login first.")
		return nil
	}
	cmd := protocol.NewCmdSimple(protocol.REQ_GET_TOPIC_LIST_CMD)
	err := self.session.Send(libnet.Json(cmd))
	if err != nil {
		log.Error(err.Error())
	}

	return err
}
Beispiel #17
0
// [msg, fromID, uuid]
func incoming_p2p_msg(self *Client, c *protocol.CmdSimple) error {
	fmt.Println(c.GetArgs()[1] + "  says : " + c.GetArgs()[0])
	if len(c.GetArgs()) >= 3 {
		cmd := protocol.NewCmdSimple(protocol.IND_ACK_P2P_STATUS_CMD)
		cmd.AddArg(c.GetArgs()[2])
		cmd.AddArg(protocol.P2P_ACK_READ)
		cmd.AddArg(c.GetArgs()[1])

		err := self.session.Send(libnet.Json(cmd))
		if err != nil {
			log.Error(err.Error())
		}
	}
	return nil
}
Beispiel #18
0
func (self *ProtoProc) procGetTopicProfile(cmd protocol.Cmd, session *libnet.Session) error {
	log.Info("procGetTopicProfile")
	var err error
	var topicCacheData *redis_store.TopicCacheData

	topicName := "<N/A>"
	resp := protocol.NewCmdSimple(protocol.RSP_GET_TOPIC_PROFILE_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())
		resp.AddArg(topicName)
	} else {
		resp.AddArg(protocol.RSP_SUCCESS)
		resp.AddArg(topicName)
		resp.AddArg(topicCacheData.CreaterID)
		for _, member := range topicCacheData.MemberList {
			resp.AddArg(member.ID)
			resp.AddArg(member.Name)
			resp.AddArg(member.Type)
		}
	}
	err = session.Send(libnet.Json(resp))
	if err != nil {
		log.Error(err.Error())
	}

	return err
}
Beispiel #19
0
func (self *HeartBeat) Beat() {
	timer := time.NewTicker(self.timeout * time.Second)
	//ttl := time.After(self.expire * time.Second)
	for {
		select {
		case <-timer.C:
			go func() {
				cmd := protocol.NewCmdSimple(protocol.SEND_PING_CMD)
				err := self.session.Send(libnet.Json(cmd))
				if err != nil {
					log.Error(err.Error())
				}
			}()
			//case <-ttl:
			//break
		}
	}
}
Beispiel #20
0
func cmd_join(self *Client, args []string) error {
	if self.bLogin == false {
		fmt.Println("NOT login yet. Please login first.")
		return nil
	}
	if len(args) != 3 {
		return common.SYNTAX_ERROR
	}
	cmd := protocol.NewCmdSimple(protocol.REQ_JOIN_TOPIC_CMD)
	cmd.AddArg(args[1])
	cmd.AddArg(args[2])

	err := self.session.Send(libnet.Json(cmd))
	if err != nil {
		fmt.Errorf(err.Error())
	}
	return err
}
Beispiel #21
0
// return (ClientID, MsgServerAddr)
func login_gateway(self *Client) error {
	fmt.Println("req GatewayServer...")

	gatewayClient, err := libnet.Dial("tcp", self.cfg.GatewayServer)
	if err != nil {
		panic(err)
	}

	cmd := protocol.NewCmdSimple(protocol.REQ_LOGIN_CMD)
	cmd.AddArg(self.clientID)
	cmd.AddArg(self.clientType)
	cmd.AddArg(self.clientPwd)

	err = gatewayClient.Send(libnet.Json(cmd))
	if err != nil {
		log.Error(err.Error())
	}

	var c protocol.CmdSimple
	err = gatewayClient.ProcessOnce(func(msg *libnet.InBuffer) error {
		log.Info(string(msg.Data))
		err = json.Unmarshal(msg.Data, &c)
		if err != nil {
			log.Error("error:", err)
		}
		return nil
	})
	if err != nil {
		log.Error(err.Error())
	}

	gatewayClient.Close()

	fmt.Println("req GatewayServer end...")

	if c.GetArgs()[0] != protocol.RSP_SUCCESS {
		log.Errorf("login gateway error: %s", c.GetArgs()[0])
		return errors.New(c.GetArgs()[0])
	}
	self.uuid = c.GetArgs()[1]
	self.msAddr = c.GetArgs()[2]

	return nil
}
Beispiel #22
0
func (self *ProtoProc) procLogout(cmd protocol.Cmd, session *libnet.Session) error {
	log.Info("procLogout")
	var err error

	ClientID := session.State.(*base.SessionState).ClientID

	resp := protocol.NewCmdSimple(protocol.RSP_LOGOUT_CMD)
	resp.AddArg(protocol.RSP_SUCCESS)

	err = session.Send(libnet.Json(resp))
	if err != nil {
		log.Error(err.Error())
	}

	self.msgServer.procOffline(ClientID)

	self.msgServer.sessionCache.Delete(ClientID)

	return err
}
func (self *ProtoProc) procReqMsgServer(cmd protocol.Cmd, session *libnet.Session) error {
	//log.Info("procReqMsgServer")
	var err error
	msgServer := common.SelectServer(self.gateway.cfg.MsgServerList, self.gateway.cfg.MsgServerNum)

	resp := protocol.NewCmdSimple(protocol.SELECT_MSG_SERVER_FOR_CLIENT_CMD)
	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
}
Beispiel #24
0
func login_server(self *Client) error {
	var err error

	self.session, err = libnet.Dial("tcp", self.msAddr)
	if err != nil {
		panic(err)
	}

	fmt.Println("req to login msg server...")
	cmd := protocol.NewCmdSimple(protocol.REQ_LOGIN_CMD)
	cmd.AddArg(self.clientID)
	cmd.AddArg(self.uuid)

	err = self.session.Send(libnet.Json(cmd))
	if err != nil {
		log.Error(err.Error())
		return err
	}

	var c protocol.CmdSimple
	err = self.session.ProcessOnce(func(msg *libnet.InBuffer) error {
		log.Info(string(msg.Data))
		err = json.Unmarshal(msg.Data, &c)
		if err != nil {
			log.Error("error:", err)
		}
		return nil
	})
	if err != nil {
		log.Error(err.Error())
	}
	if c.GetArgs()[0] != protocol.RSP_SUCCESS {
		log.Errorf("login msgserver error: %s", c.GetArgs()[0])
		return errors.New(c.GetArgs()[0])
	}

	fmt.Println("login msg server SUCCESS")
	return nil
}
Beispiel #25
0
// send <msg>[ <topic>]
func cmd_send(self *Client, args []string) error {
	if self.bLogin == false {
		fmt.Println("NOT login yet. Please login first.")
		return nil
	}
	if self.clientType == protocol.DEV_TYPE_CLIENT {
		if len(args) != 3 {
			return common.SYNTAX_ERROR
		}
	} else if len(args) != 2 {
		return common.SYNTAX_ERROR
	}

	cmd := protocol.NewCmdSimple(protocol.REQ_SEND_TOPIC_MSG_CMD)
	cmd.AddArg(args[1])

	if self.clientType == protocol.DEV_TYPE_CLIENT {
		cmd.AddArg(args[2])
	}

	err := self.session.Send(libnet.Json(cmd))
	return err
}
Beispiel #26
0
/*
   REQ_CREATE_TOPIC_CMD
   arg0: TopicName     //群组名
   arg1: ClientName    //用户在Topic中的Name, 比如老爸/老妈
*/
func (self *ProtoProc) procCreateTopic(cmd protocol.Cmd, session *libnet.Session) error {
	log.Info("procCreateTopic")
	var err error

	topicName := cmd.GetArgs()[0]
	ClientName := cmd.GetArgs()[1]
	ClientID := session.State.(*base.SessionState).ClientID
	ClientType := session.State.(*base.SessionState).ClientType

	resp := protocol.NewCmdSimple(protocol.RSP_CREATE_TOPIC_CMD)

	if len(cmd.GetArgs()) != 2 {
		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 exist in CACHE", topicName)
			err = common.TOPIC_EXIST
		} else {
			log.Infof("TOPIC %s not exist in CACHE", topicName)
			topicStoreData, _ := self.msgServer.mongoStore.GetTopicFromCid(topicName)
			if topicStoreData != nil {
				log.Infof("TOPIC %s exist in STORE", topicName)
				err = common.TOPIC_EXIST
			} else {
				log.Infof("TOPIC %s not exist in STORE", topicName)

				// create the topic store
				log.Infof("Create topic %s in STORE", topicName)
				topicStoreData = mongo_store.NewTopicStoreData(topicName, ClientID)
				err = self.msgServer.mongoStore.Set(topicStoreData)
				if err != nil {
					log.Error(err.Error())
					goto ErrOut
				}
				log.Infof("topic %s created in STORE", topicName)

				// create the topic cache
				log.Infof("Create topic %s in CACHE", topicName)
				topicCacheData = redis_store.NewTopicCacheData(topicStoreData)
				err = self.msgServer.topicCache.Set(topicCacheData)
				if err != nil {
					log.Error(err.Error())
					goto ErrOut
				}
				log.Infof("topic %s created in CACHE", topicName)

				member := mongo_store.NewMember(ClientID, ClientName, ClientType)
				err = self.msgServer.procJoinTopic(member, topicName)

			}
		}

	}

ErrOut:
	if err != nil {
		resp.AddArg(err.Error())
		resp.AddArg(topicName)
	} else {
		resp.AddArg(protocol.RSP_SUCCESS)
		resp.AddArg(topicName)
		resp.AddArg(ClientName)
	}
	err = session.Send(libnet.Json(resp))
	if err != nil {
		log.Error(err.Error())
	}

	return err

	/*
		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
}
Beispiel #27
0
func main() {
	flag.Parse()
	cfg, err := LoadConfig(*InputConfFile)
	if err != nil {
		glog.Error(err.Error())
		return
	}

	fmt.Println("req GatewayServer...")

	gatewayClient, err := libnet.Dial("tcp", cfg.GatewayServer)
	if err != nil {
		panic(err)
	}

	//glog.Info("...")
	cmd := protocol.NewCmdSimple(protocol.REQ_MSG_SERVER_CMD)

	err = gatewayClient.Send(libnet.Json(cmd))
	if err != nil {
		glog.Error(err.Error())
	}

	fmt.Println("input id :")
	var input string
	if _, err := fmt.Scanf("%s\n", &input); err != nil {
		glog.Error(err.Error())
	}
	var c protocol.CmdSimple
	err = gatewayClient.ProcessOnce(func(msg *libnet.InBuffer) error {
		glog.Info(string(msg.Data))
		err = json.Unmarshal(msg.Data, &c)
		if err != nil {
			glog.Error("error:", err)
		}
		return nil
	})
	if err != nil {
		glog.Error(err.Error())
	}

	gatewayClient.Close()

	fmt.Println("req GatewayServer end...")

	msgServerClient, err := libnet.Dial("tcp", string(c.GetArgs()[0]))
	if err != nil {
		panic(err)
	}

	fmt.Println("send your id...")
	cmd = protocol.NewCmdSimple(protocol.SEND_CLIENT_ID_CMD)
	cmd.AddArg(input)

	err = msgServerClient.Send(libnet.Json(cmd))
	if err != nil {
		glog.Error(err.Error())
	}

	go heartBeat(cfg, msgServerClient)

	//glog.Info("the msg you want to send...")

	go msgServerClient.Process(func(msg *libnet.InBuffer) error {
		//glog.Info(string(msg.Data))
		err = json.Unmarshal(msg.Data, &c)
		if err != nil {
			glog.Error("error:", err)
		}
		fmt.Println(c.GetArgs()[1] + "  says : " + c.GetArgs()[0])

		return nil
	})

	for {
		cmd = protocol.NewCmdSimple(protocol.SEND_MESSAGE_P2P_CMD)

		fmt.Println("send the id you want to talk :")
		if _, err = fmt.Scanf("%s\n", &input); err != nil {
			glog.Error(err.Error())
		}

		cmd.AddArg(input)

		fmt.Println("input msg :")
		if _, err = fmt.Scanf("%s\n", &input); err != nil {
			glog.Error(err.Error())
		}

		cmd.AddArg(input)

		fmt.Println("input my ID :")
		if _, err = fmt.Scanf("%s\n", &input); err != nil {
			glog.Error(err.Error())
		}

		cmd.AddArg(input)

		err = msgServerClient.Send(libnet.Json(cmd))
		if err != nil {
			glog.Error(err.Error())
		}
	}

	defer msgServerClient.Close()

	// msgServerClient.Process(func(msg *libnet.InBuffer) error {
	// 	glog.Info(string(msg.Data))
	// 	return nil
	// })

	glog.Flush()
}
Beispiel #28
0
/*
   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] > 1 {
			// exactly in this server, just broadcasting
			topic_msg_resp.ChangeCmdName(protocol.IND_SEND_TOPIC_MSG_CMD)
			log.Warningf("topic %s has %d member(s) in this server", topicName, topicCacheData.AliveMemberNumMap[self.msgServer.cfg.LocalIP])
			for _, mID := range topicCacheData.MemberList {
				if mID.ID != ClientID && 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)
			topic_msg_resp.ChangeCmdName(protocol.REQ_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
}
Beispiel #29
0
/*
   IND_ACK_P2P_STATUS_CMD
   arg0: uuid // 发送方知道uuid对应的已发送的消息已送达
   arg1: SENT/READ // 发送方知道uuid对应的消息状态:已送达/已读
*/
func (self *ProtoProc) procP2PAckStatus(fromID string, uuid string, status string) error {
	log.Info("procP2PAckStatus")
	//var err error

	p2psd, err := self.msgServer.p2pStatusCache.Get(fromID)
	if p2psd == nil {
		p2psd = redis_store.NewP2pStatusCacheData(fromID)
	}
	p2psd.Set(uuid, status)

	if status == protocol.P2P_ACK_FALSE {
		return nil
	}

	sessionCacheData, err := self.msgServer.sessionCache.Get(fromID)
	if sessionCacheData == nil {
		log.Warningf("no cache ID : %s, err: %s", fromID, err.Error())
		sessionStoreData, err := self.msgServer.mongoStore.GetSessionFromCid(fromID)
		if sessionStoreData == nil {
			// not registered
			log.Warningf("no store ID : %s, err: %s", fromID, err.Error())
			self.msgServer.p2pStatusCache.Delete(fromID)
			return err
		}
	}
	if sessionCacheData == nil || sessionCacheData.Alive == false {
		// offline
		log.Info(fromID + " | is offline")
		omrd, err := common.GetOfflineMsgFromOwnerName(self.msgServer.offlineMsgCache, fromID)
		log.Info(omrd)
		if err != nil {
			log.Error(err.Error())
			return err
		}
		if omrd == nil {
			omrd = redis_store.NewOfflineMsgCacheData(fromID)
		}
		omrd.AddMsg(redis_store.NewOfflineMsgData(protocol.IND_ACK_P2P_STATUS_CMD /*fromID*/, status, uuid))

		err = self.msgServer.offlineMsgCache.Set(omrd)

		if err != nil {
			log.Error(err.Error())
			return err
		}
	} else {
		// online
		resp := protocol.NewCmdSimple(protocol.IND_ACK_P2P_STATUS_CMD)
		resp.AddArg(uuid)
		resp.AddArg(status)
		log.Info(fromID + " | is online")
		if sessionCacheData.MsgServerAddr == self.msgServer.cfg.LocalIP {
			log.Info("in the same server")

			if self.msgServer.sessions[fromID] != nil {
				self.msgServer.sessions[fromID].Send(libnet.Json(resp))
				if err != nil {
					log.Error(err.Error())
					return err
				}
			}
		} else {
			log.Info("not in the same server")
			if self.msgServer.channels[protocol.SYSCTRL_SEND] != nil {
				resp.AddArg(fromID)
				_, err = self.msgServer.channels[protocol.SYSCTRL_SEND].Channel.Broadcast(libnet.Json(resp))
				if err != nil {
					log.Error(err.Error())
					return err
				}
			}
		}
	}

	return nil
}
Beispiel #30
0
func (self *ProtoProc) procSendMessageP2P(cmd protocol.Cmd, session *libnet.Session) error {
	log.Info("procSendMessageP2P")
	var err error
	var sessionCacheData *redis_store.SessionCacheData
	var sessionStoreData *mongo_store.SessionStoreData
	var uuid string
	var send2ID string
	var send2Msg string

	fromID := session.State.(*base.SessionState).ClientID

	resp := protocol.NewCmdSimple(protocol.RSP_SEND_P2P_MSG_CMD)

	if len(cmd.GetArgs()) != 2 {
		log.Warningf("syntax error: (id,msg) needed")
		err = common.SYNTAX_ERROR
		goto errout
	}

	send2ID = cmd.GetArgs()[0]
	send2Msg = cmd.GetArgs()[1]

	sessionCacheData, err = self.msgServer.sessionCache.Get(send2ID)
	if sessionCacheData == nil {
		sessionStoreData, err = self.msgServer.mongoStore.GetSessionFromCid(send2ID)
		if sessionStoreData == nil {
			log.Warningf("send2ID %s not found", send2ID)
			err = common.NOTFOUNT
			goto errout
		}
	}

	uuid = common.NewV4().String()
	log.Info("uuid : ", uuid)

	self.procP2PAckStatus(fromID, uuid, protocol.P2P_ACK_FALSE)

	if sessionCacheData == nil || sessionCacheData.Alive == false {
		//offline
		log.Info("procSendMessageP2P: " + send2ID + " | is offline")

		omrd, err := self.msgServer.offlineMsgCache.Get(send2ID)
		log.Info(omrd)
		if err != nil {
			log.Error(err.Error())
		}
		if omrd == nil {
			omrd = redis_store.NewOfflineMsgCacheData(send2ID)
		}
		omrd.AddMsg(redis_store.NewOfflineMsgData(send2Msg, fromID, uuid))

		err = self.msgServer.offlineMsgCache.Set(omrd)

		if err != nil {
			log.Error(err.Error())
			goto errout
		}
	} else if sessionCacheData.MsgServerAddr == self.msgServer.cfg.LocalIP {
		log.Info("procSendMessageP2P: in the same server")
		req := protocol.NewCmdSimple(protocol.IND_SEND_P2P_MSG_CMD)
		req.AddArg(send2Msg)
		req.AddArg(fromID)
		// add uuid
		req.AddArg(uuid)

		if self.msgServer.sessions[send2ID] != nil {
			self.msgServer.sessions[send2ID].Send(libnet.Json(req))
			if err != nil {
				log.Error(err.Error())
				goto errout
			}
			self.procP2PAckStatus(fromID, uuid, protocol.P2P_ACK_SENT)
		}
	} else {
		log.Info("procSendMessageP2P: not in the same server")
		if self.msgServer.channels[protocol.SYSCTRL_SEND] != nil {
			cmd.AddArg(fromID)
			//add uuid
			cmd.AddArg(uuid)
			_, err = self.msgServer.channels[protocol.SYSCTRL_SEND].Channel.Broadcast(libnet.Json(cmd))
			if err != nil {
				log.Error(err.Error())
				goto errout
			}
			//self.procP2PAckStatus(fromID, uuid, protocol.P2P_ACK_SENT)
		}
	}
errout:
	if err != nil {
		resp.AddArg(err.Error())
	} else {
		resp.AddArg(protocol.RSP_SUCCESS)
		resp.AddArg(uuid)
	}
	err = session.Send(libnet.Json(resp))
	if err != nil {
		log.Error(err.Error())
	}

	return err
}