//机器人管理器心跳
func (rbMng *RobotMng) Heart() {

	//500 ms 检测一次
	rbMng.ticker = time.NewTicker(defDur) //创建时钟
	for {
		// del close
		select {
		case id := <-rbMng.delCh: //删除机器人
			rbMng.DelRobot(id)
		case <-rbMng.closeCh: //关闭机器人管理器心跳
			elog.LogDebugln(" rbMng heart close ")
			return
		case <-rbMng.ticker.C:
			//定时检测
			diff := defRobotNum - len(rbMng.robots) //计算缺少的机器人
			if diff > 0 {
				elog.LogDebugln(" RobotMng heart : ", "diff ", diff)
				for i := 0; i < diff; i++ {
					rbMng.NewRobot() //补足缺少的机器人
				}
			}
		default:
		}
	}
}
//启动机器人
func (r *Robot) Run() {

	elog.LogDebug(" robot %d begin run ", r.id)
	var err error
	r.addr, err = net.ResolveTCPAddr("tcp", gateAddr) //解析服务器地址
	if err != nil {
		elog.LogErrorln(gateAddr, ":resolve tcp addr fail, please try: 127.0.0.1:3563, fail: ", err)
		return
	}
	r.tcpConn, err = net.DialTCP("tcp", nil, r.addr) //连接服务器
	if err != nil {
		elog.LogErrorln("connect server fail , because :", err)
		return
	}

	elog.LogInfoln(" connect  server sucess :", r.id, r.tcpConn.RemoteAddr().String())
	r.state = kRobotActive //设置机器人状态

	r.waitGroup.Run(r.SendLoop) //启动发送循环
	r.waitGroup.Run(r.RecvLoop) //启动接收循环

	r.ticker = time.NewTicker(defDur) //启动机器人时钟

	defer r.Close() //延迟关闭机器人
	for {
		select {
		case <-r.closeCh: //关闭通道
			elog.LogDebugln("update loop begin stop ")
			return
		case <-r.ticker.C: //时钟到时
			//逻辑处理
			r.update()
			//elog.LogInfoln("robot :", r.id, "heart :", t)
		default:
		}
	}
}
//删除机器人
func (rbMng *RobotMng) DelRobot(id uint32) {
	rbMng.mapMutex.Lock()         //加锁
	defer rbMng.mapMutex.Unlock() //解锁
	delete(rbMng.robots, id)      //删除映射
	elog.LogDebugln("del robot ", id)
}
//添加机器人
func (rbMng *RobotMng) AddRobot(r *Robot) {
	rbMng.mapMutex.Lock()         //加锁
	defer rbMng.mapMutex.Unlock() //解锁
	rbMng.robots[r.id] = r        //添加映射
	elog.LogDebugln("add robot ", r.id)
}