mangos(一)概述与消息处理机制

本文介绍了开源服务器框架mangos,详细解析了其线程分布,包括WorldRunnable、WorldSession等类的作用。文章强调了mangos的非实时处理策略和事件分发机制,以及如何通过函数指针优化性能。此外,还讨论了数据库操作的处理方式和单线程逻辑,以减少锁竞争和提高系统性能。
摘要由CSDN通过智能技术生成

一、概述

想看下开源的服务器框架,本以为挺复杂,但mangos代码写的很清楚。mangos不是一个魔兽私服模拟器,它是一个开源的自由软件项目,是用c++和C#编程语言,实现的一个支持大型多人在线角色扮演游戏服务器的程序框架。svn的路径:http://svn.code.sf.net/p/mangos/code/trunk 下载下来貌似有100多兆,我用的vs2005编译vc8工程release版本一次就编译过了。

主目录中文件夹有:
contrib 第三方的工具
dep 依赖的开源库ace sqlite等
src 项目代码
sql 数据库脚本

src目录下文件夹有:
bindings文件夹中包含脚本文件,应该是对脚本进行绑定的。
framework文件夹中包括一些游戏框架,其中包括网络框架,游戏系统框架,工具,平台等内容。
game文件夹中应该是游戏的文件,包括世界系统,战斗系统,游戏事件,游戏场景等的实现。
mangosd文件夹中是mangosd的主程序,包括程序的入口等。
realmd 文件夹中是游戏区域信息,包括RealmList等内容。
shared文件夹中 应该是公用的函数和库,database的内容包含在其中。

线程分布:
1、主线程 main—- 主要功能:初始化world、创建子线程、回收资源
2、WorldRunnable ——-主线程
3、CliRunnable —–调试线程 command line
4、RARunnable ——-Remote Administration 处理远程管理命令?
5、MaNGOSsoapRunnable—协议
6、FreezeDetectorRunnable —- 心跳检测
7、SqlDelayThread — 数据线程
8、PatcherRunnable —- 给客户端升级(发送补丁文件)

这里对于线程类的命名都是以Runnable开始,以继承的方式实现线程类,从而对线程的分布一目了然,并且对类有一定说明作用。

事件分发和处理:
WorldRunnable::run—World:update—-World:UpdateSessions—WorldSession::Update(一个socket内所有事件)—各种各样的handler

二、WorldRunnable类

/// Heartbeat for the World
void WorldRunnable::run()
{
    ///- Init new SQL thread for the world database
    WorldDatabase.ThreadStart();                                // let thread do safe mySQL requests (one connection call enough)
    sWorld.InitResultQueue();

    uint32 realCurrTime = 0;
    uint32 realPrevTime = getMSTime();

    uint32 prevSleepTime = 0;                               // used for balanced full tick time length near WORLD_SLEEP_CONST

    ///- While we have not World::m_stopEvent, update the world
    while (!World::m_stopEvent)
    {
        ++World::m_worldLoopCounter;
        realCurrTime = getMSTime();

        uint32 diff = getMSTimeDiff(realPrevTime,realCurrTime);

        sWorld.Update( diff );
        realPrevTime = realCurrTime;

        // diff (D0) include time of previous sleep (d0) + tick time (t0)
        // we want that next d1 + t1 == WORLD_SLEEP_CONST
        // we can't know next t1 and then can use (t0 + d1) == WORLD_SLEEP_CONST requirement
        // d1 = WORLD_SLEEP_CONST - t0 = WORLD_SLEEP_CONST - (D0 - d0) = WORLD_SLEEP_CONST + d0 - D0
        if (diff <= WORLD_SLEEP_CONST+prevSleepTime)
        {
            prevSleepTime = WORLD_SLEEP_CONST+prevSleepTime-diff;
            ZThread::Thread::sleep(prevSleepTime);
        }
        else
            prevSleepTime = 0;
    }

    ... // 清理资源
}
  1. 这是游戏世界的驱动线程,一开始很困惑“Heartbeat”难道是用来保持长连接用的?其实这里的Heartbeat应该理解为是整个世界的驱动的地方,像人的心脏,汽车的发动机之类。

  2. WorldDatabase.ThreadStart();这里名字很明确,“ThreadStart”,线程启动,如果内部带线程运行,名字中最好体现,不要叫做“Start”之类。同样结束线程名字为WorldDatabase.ThreadEnd();

  3. 在线程中,每次处理完都sleep了一段时间,有注释如下
    // diff (D0) include time of previous sleep (d0) + tick time (t0)
    // we want that next d1 + t1 == WORLD_SLEEP_CONST
    // we can’t know next t1 and then can use (t0 + d1) == WORLD_SLEEP_CONST requirement
    // d1 = WORLD_SLEEP_CONST - t0 = WORLD_SLEEP_CONST - (D0 - d0) = WORLD_SLEEP_CONST + d0 - D0

这可能是游戏服务器中的特殊的部分,游戏服务器不需要“实时”处理用户的请求,只需要让用户觉得是“实时”的就够了。就像电视,不论是液晶的合适CRT的都有个刷新频率。而且如果使用“实时”处理的方式还会引入很多不必要的问题,例如,如果实时处理没有sleep,假设服务器能够处理,用户通过某种方法,在1秒内发送了1000次的“出拳”指令,如果不加以处理,那么一碰到这拳头其他人就挂了。这个固定的处理时间,也给整个游戏世界定了一个时间的最小片段,动作频率的最小片段,方便以后各种业务的处理。

sleep会不会浪费cpu呢?不会,因为只有在线程能够在一个WORLD_SLEEP_CONST处理完所有操作时候才会sleep,如果这个处理线程一直是满负荷的,那么这个线程也会一直工作。

计算方法看着比较复杂,其实不难。不考虑其他情况,假如线程每次都能处理完(diff<=WORLD_SLEEP_CONST+prevSleepTime),
那么有DO = d0 + t0, d1 = WORLD_SLEEP_CONST + d0 - D0 = WORLD_SLEEP_CONST - t0;
那么假设WORLD_SLEEP_CONST为100ms,处理花费10ms(t0),那么就sleep90ms(100 - 10)就可以了;然后,diff = 10 + 90 = 100ms,这种理想的情况下,diff一直是100ms,但是在线程很忙的时候,sWorld.Update时间大于100ms时候,也就是diff>WORLD_SLEEP_CONST+prevSleepTime <==> t0 + d0 > WORLD_SLEEP_CONST+prevSleepTime(d0),即t0 > WORLD_SLEEP_CONST时候,diff就不等100了,这个时候prevSleepTime,diff等于sWorld.Update。

mangos不是一个魔兽私服模拟器,它是一个开源的自由软件项目,是用c++和C#编程语言,实现的一个支持大型多人在线角色扮演游戏服务器的程序框架,在这个框架下,它理论上应该支持任何客户端的网络游戏,由于现在很多人使用魔兽世界来对它进行测试,所以针对魔兽世界的脚本和数据库文件比较完善,很多人就利用这个开源项目来实现魔兽私服。   首先,mangos项目是一个开源的自由软件(如同linux或者firefox),并且遵守其中最为严格的GPL协议,也就是保证源代码绝对的自由,要了解什么是开源软件,自由软件请自己搜索这方面的资料。   其次开发小组一再强调,这是个研究,教育性质的对怎样开发大型网游的服务器端有好处的项目,是一个技术细节毫无保留向公众开放的软件,是一件很有意义的事情,如果你使用它作为盈利目的,那你本身就违反了软件的协议。所以任何利用mangos项目进行私服活动的组织和个人都违反了mangos的宗旨,mangos项目也不会对它们负责。   mangos的技术细节上是这样的,核心部分是个和特定游戏没有关系的核心框架程序,主要是进行进程调度,创造世界,建立心跳机,处理网络接入等。数据库也是使用的开源数据库软件MySQL,编译器使用的是GCC。至于游戏内容数据库,游戏人物,时间,世界脚本,都是由这个核心程序所支持的扩展脚本来实现,所以有一些独立出来的项目专门模拟魔兽世界来开发支持mangos的核心程序。现在mangos的核心程序已经放到著名的协同开发网站sourceforge上开发了,使用的版本控工具是subversion,(目前已经迁移到GIT)。大家都可以从sourceforge的subversion数据库中下载最新的源代码程序。   另外有点要注意的是,开源项目是很容易被利用的,有时候有的公司开发了一个软件说是自己做的其实内核都是别人的开源内核,但是公司又不承认,利用了别人的劳动成果赚钱不说,既不回报社区,也对开源自由软件造成了很大的伤害。所以大家注意了,如果看到一个和魔兽世界很像的什么网络游戏?要想想是不是利用的mangos的核心程序。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值