最后一战(LastBattle)服务器源码分析8.1——定时器

定时器:

目前主流的定时器实现包括时间轮和最小堆,最后一战是用最小堆(优先队列)实现的定时器,下面先分析下其具体实现:

	typedef std::function<void(int64_t, int64_t)> HeartbeatCallback;

	typedef int64_t TimeKey;
	class CBattleTimer
	{
	public:
		CBattleTimer(void);
		~CBattleTimer(void);
		//服务器启动之初调用该函数初始化m_InitTime作为相对时间的对照标准
		void			SetInitTime(ptime& time){m_InitTime = time;}
        //添加定时器  参数:回调函数,定时时间,是否延续
		int64_t			AddTimer(HeartbeatCallback pHeartbeatCallback, int64_t interval, bool ifPersist);
		void			RemoveTimer(int64_t timerID){m_InvalidTimerSet.insert(timerID);}
		//获取最近超时时间
		bool			GetNearestWaitTime(ptime& time);
        //每个tick中调用run()函数尝试处理当前超时的定时器
		void			Run();
		bool			IsEmpty()const{return m_ToAddTimer.empty() && m_ThreadTimerQueue.empty();}
	private:
	    //为每个定时器分配唯一id,用于索引查找定时器
		int64_t			GetTimerSequence(){return ++m_TimerSeq;}
        //定时器数据结构
		struct ThreadTimer{
			TimeKey nextexpiredTime;//下次超时时间
			TimeKey lastHandleTime;//上次超时时间
			int64_t	sequence;//唯一id
			HeartbeatCallback pHeartbeatCallback;//回调函数
			int64_t interval;//定时时间
			bool ifPersist;//是否持续
			ThreadTimer(TimeKey& nextexpiredTime, TimeKey& lastHandleTime, HeartbeatCallback pHeartbeatCallback, int64_t interval, int64_t sequence, bool ifPersist)
			:nextexpiredTime(nextexpiredTime), lastHandleTime(lastHandleTime), pHeartbeatCallback(pHeartbeatCallback), interval(interval), sequence(sequence), ifPersist(ifPersist){}
			//重载<运算符,用于优先队列中排序
			bool operator <(const ThreadTimer& sThreadTimer) const{
				if (nextexpiredTime != sThreadTimer.nextexpiredTime){
					return nextexpiredTime > sThreadTimer.nextexpiredTime;
				}
				return  sequence > sThreadTimer.sequence;
			}
		};
        //获取目前时间与m_InitTime的相对时间,精确到微秒
		TimeKey GetInternalTime();

		std::priority_queue<ThreadTimer>  m_ThreadTimerQueue;//优先队列,队列顶部永远都是最近要超时的定时器
		vector<ThreadTimer>			m_ToAddTimer;//添加定时器的临时队列
		vector<ThreadTimer>			m_PendingTimer;//将要执行的定时器临时队列
		set<int64_t>	m_InvalidTimerSet;//已经删除的定时器集合
		int64_t	m_TimerSeq;//唯一id生成
		ptime	m_InitTime;//相对时间对照点
	};

服务器在每个tick中调用 run() 函数将添加定时器的临时队列 m_ToAddTimer 中的数据添加到优先队列 m_ThreadTimerQueue中,然后从优先队列头部遍历,去除m_InvalidTimerSet所有已经删除的定时器,然后找出所有需要执行的已经超时的定时器,放到执行临时队列 m_PendingTimer 执行回调函数。

优点:

  • 实现简单,基于优先队列对定时器进行排序,简单高效。

缺点:

  • 1.仅用于玩家在线时的定时功能,玩家下线时删除。无法作为玩家离线定时进行存档。
  • 2.轻量级的定时器,数据量对效率有很大影响。
  • 3.测试不方便,在线更改时间对定时器没有影响,这在真实生产环境下测试将非常不方便。

改进:

  • 1.为每个定时器生成全局唯一guid,同时将定时器分为需要存档和不需要存档两类,将需要存档的定时器在玩家下线或服务器关闭时存档,在玩家上线或者服务器重启后加载数据构建定时器。
  • 2.数据量大时可以选用时间轮定时器(下文介绍)
  • 3.对游戏中的相对时间支持gm命令修改,方便实际生产环境的测试。

时间轮定时器:时间轮定时器介绍传送门

优点:

  • 重量级的定时器,可承载较大的数据量。可用于服务器底层网络连接中剔除超时网络连接。

缺点:

  • 1.实现复杂,特别是多级时间轮定时器。
  • 2.更改时间对时间轮影响大,数据量大时耗时太久。

提供一个三级时间轮定时器的c++实现供大家参考学习:点击传送门

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
花钱买来的 ,自己亲测可执行,~ 下载下来是个 txt文本,里面有 下载地址,跟密码! 这款游戏 类似王者荣耀! 客户端用 unity 4.6直接打开编译,生成exe,或者安卓APK(需要装JDK,SDK), 服务端按教程操作就可以了! 最后一战OL》是国内首款原创精品MOBA手游,是一款由前暴雪文案亲自操刀世界观,日韩专业团队打造美术场景,新加坡团队精心制作战斗音乐的旷世之作!' e9 H' Q* w: Z5 r 《最后一战OL》超快速的匹配对战、默契的团队协作给你带来意犹未尽的快感,在传统的MOBA游戏中融入了诸多创新玩法,吸附野怪技能、祭坛超级兵种、怒气超神爆发的同时多样性的英雄供你挑选!百余种装备搭配助您打造最强王者,超神不断!带上你的战友并肩协作,一起来体验《最后一战》这款引领潮流的精品手游吧!2 n" r$ Q' |+ \; w$ A' q! ^ 本资源是完整的,可以编译进游戏的。前端采用Unity3D,可以在 Unity3D 4.0 + 以上版本编译运行,后端服务器部分采用 C++开发,需要在 VS 2010 下完成编译。数据库采用 MySQL。 最后一战经过测试,可以进游戏,搭建很简单,只要几步简单的操作就能跑起来 1、客户端打开 用的u3d 4.6版本打开的,没有发现什么问题,可以直接编译 2、服务端 首先用vs2010打开server》Allserver.sln,点击编译,编译要花点时间,编译完成后,可能会出现几个红色的文字,不用管他,暂时没发现有影响。 然后打开Server\Bin\x64\Release\dbsql\Rebuild.bat,创建数据库,在这里要编辑下Rebuild.bat里面的内容,记事本打开,然后将-uroot -p123321,改成你自己的数据库名称和密码, root改成你的数据库名称,123321改成你自己的数据库密码。+ H7 s. z7 f/ g8 Q9 V+ G 数据库创建完成后,打开server》start.bat,打开的几个窗口也会有红字的文字,不用管,暂时没发现有影响。 注意点: 1、数据库安装-》数据库安装是个难活,我在自己电脑上按了N次,没成功,总是提示联不到数据库,可能跟系统有关系,回头再研究下 2、服务端编译,vs在编译后有红色的文字,之前以为是报错,一直改,没解决,后来不管他了,直接跑,居然过了。。。。 3、修改rebuild.bat,一定要修改成你自己的数据库名字和密码,不然创建不成功。 3、编译u3d客户端,就可以进游戏了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值