请选择 进入手机版 | 继续访问电脑版

NoahFrame

 找回密码
 Register Now
搜索
热搜: redis mysql tutorial
查看: 2967|回复: 4

第四章 NF分布式服务器解决方案--通用的数据驱动模型

[复制链接]

30

主题

111

帖子

632

积分

Administrator

Rank: 9Rank: 9Rank: 9

积分
632
发表于 2016-12-30 09:29:50 | 显示全部楼层 |阅读模式
NF(https://github.com/ketoo/NoahGameFrame)全称为 NoahFrame/NoahGameFrame。


NF最早为客户端设计,后来随着时代的变化,而为自己又转为服务器开发,故在吸收了众多引擎的优点后(包含Ogre的插件模式&模块化管理机制,Bigworld的数据管理&配置机制,类似MYGUI的接口层次设计),经过多年演化和实践,变成了一套游戏开发J解决方案。方案中包含开源的服务器架构,网络库(站在libevent的肩膀上),和unity3d的demo源码。现在NF已经在多个公司的多个项目中使用,其中包含知名产品 《全民无双》。


关键词


NoahGameFrame/NoahFrame/NF
集群/负载均衡/分布式
网关服务器 GateServer 心跳 多线程/线程池 开源网络框架/模型
一致性hash算法/ConsistentHash
游戏开发中的设计模式/数据结构
Socket Nagle/粘包/开源游戏服务器/ Game Server



数据驱动,在NF的观念里面,意思就是数据的变更来驱动业务逻辑的运算,而非通常编程中的while循环来不断的检测内容而驱动业务逻辑的运算。真正的意思就是设计模式中的观察者模式,但是怎么用好观察者模式是一门很大的学问,君不见多少公司多少高手,就折在这里了。

数据驱动有2个必要条件,数据和驱动模式,驱动模式已经说了是观察者模式,那么怎么结合呢?我们回忆上一章 属性管理思想介绍,看如何结合俩者。
首先有一点很关键,数据驱动,何时驱动这个时机问题,在我的想象中,就是当有效数据变化的时候才会驱动运行新的逻辑。比如HP=10 ---> HP =20此时会驱动逻辑运行,而我们的HP是一个这样的类(Property)

  1. class NFCProperty
  2. {
  3.     public bool SetInt(const NFINT64 value);
  4.     public bool SetFloat(const double value);
  5.     public bool SetString(const std::string& value);
  6.     public bool SetObject(const NFGUID& value);
  7.     public bool SetVector2(const NFVector2& value);
  8.     public bool SetVector3(const NFVector3& value);

  9.     public NFINT64 GetInt() const;
  10.     public double GetFloat() const;
  11.     public const std::string& GetString() const;
  12.     public const NFGUID& GetObject() const;
  13.     public const NFVector2& GetVector2() const;
  14.     public const NFVector3& GetVector3() const;

  15.     public void RegisterCallback(PROPERTY_EVENT_FUNCTOR_PTR cb);

  16.     private int OnEventHandler(const NFIDataList::TData& oldValue, const NFIDataList::TData& newValue);
  17.     private vector<PROPERTY_EVENT_FUNCTOR_PTR> mtPropertyCallback;
  18. }
复制代码



接下来实现观察着模式来驱动逻辑,观察着模式少不了注册和事件触发,分别为RegisterCallback 和 OnEventHandler 函数,而PROPERTY_EVENT_FUNCTOR_PTR则为回调函数(委托),他们的实现分别是:


  1. void NFCProperty::RegisterCallback(const PROPERTY_EVENT_FUNCTOR_PTR& cb)
  2. {
  3.      mtPropertyCallback.push_back(cb);
  4. }

  5. int NFCProperty::OnEventHandler(const NFIDataList::TData& oldVar, const NFIDataList::TData& newVar)
  6. {
  7.     TPROPERTYCALLBACKEX::iterator it = mtPropertyCallback.begin();
  8.     TPROPERTYCALLBACKEX::iterator end = mtPropertyCallback.end();
  9.     for (it; it != end; ++it)
  10.     {
  11.         
  12.         PROPERTY_EVENT_FUNCTOR_PTR& pFunPtr = *it;
  13.         PROPERTY_EVENT_FUNCTOR* pFunc = pFunPtr.get();
  14.         //对象ID,属性名,OLD属性值,NEW属性值
  15.         pFunc->operator()(mSelf, msPropertyName, oldVar, newVar);
  16.     }

  17.     return 0;
  18. }
复制代码


其中RegisterCallback函数,当某个模块对这个属性有兴趣的时候(或者说业务需求需要的时候),才会调用此函数进行回调函数注册,而注册过的函数会被在Property的内存中,等待事件触发被调用。存储下面我们来看,当数值改变的时候(SetInt, SetString等函数),触发回调的过程:

  1. bool NFCProperty::SetInt(const NFINT64 value)
  2. {
  3.     if (eType != TDATA_INT)
  4.     {
  5.         return false;
  6.     }

  7.     if (value == GetInt())
  8.     {
  9.         return false;
  10.     }

  11.     NFCDataList::TData oldValue;
  12.     oldValue = GetInt();

  13.     mxData->SetInt(value);

  14.     OnEventHandler(oldValue, value);

  15.     return true;
  16. }
复制代码



代码中的NFCDataList::TData,可以理解为c#/java语言中的object,c++则理解为联合体就行(Property的简单体),总之它能兼容我们的基础数据,这就够了。
因此,当有效数据变化的时候就会调用回调函数(委托),从而达到数据驱动逻辑的目的。看起来很简单,但是实际大范围应用起来后,可以得到意向不到的效果,不仅仅是效率高,结合NFClass,开发效率直逼火箭速度。同时,复杂一点的record(二维记录表)的执行原理,和property的原理几乎一模一样,不过是在回调函数接口中,增加了row和col的参数,却几乎可以应用在所有的逻辑系统中。

NF引擎中大量使用了这种基础技术,来达到逻辑解耦的目的,比如是否广播,是否存档,广播范围,这些属性均是属性对象的属性,配合数据驱动(甚至可以加上脚本),可以很简单的做出很多很复杂的自动化功能,同时几何级降低了维护成本。


NF项目为开源的分布式服务器解决方案,其中包含了网络库,actor库,以及数据驱动等新技术,能大幅提升开发效率节省开发周期以及提高程序的稳定性。
项目地址 https://github.com/ketoo/NoahGameFrame
如感觉对您有帮助,请给与star,同时也邀请广大同行参与开发和维护,作者QQ 342006,交流QQ群 341159815。
欢迎转载,转载请注明来源,本文版权归作者所有!




回复

使用道具 举报

0

主题

1

帖子

18

积分

Newbie

Rank: 1

积分
18
发表于 2017-10-20 17:59:25 | 显示全部楼层
给博主点个赞,这应该是近几年来写的最详细的游戏c++服务端框架了;   继续加油!!!!!!!!!!!:
回复 支持 反对

使用道具 举报

1

主题

5

帖子

25

积分

Newbie

Rank: 1

积分
25
发表于 2018-6-29 10:23:01 | 显示全部楼层
给博主点个赞,我用类似的观察者模式替换过switch逻辑,用起来很优雅。顺便表扬一下NF的代码风格很规范,比kbengine强太多了
回复 支持 反对

使用道具 举报

30

主题

111

帖子

632

积分

Administrator

Rank: 9Rank: 9Rank: 9

积分
632
 楼主| 发表于 2018-7-5 18:11:19 | 显示全部楼层
jiangwang 发表于 2018-6-29 10:23
给博主点个赞,我用类似的观察者模式替换过switch逻辑,用起来很优雅。顺便表扬一下NF的代码风格很规范,比 ...

多谢支持
回复 支持 反对

使用道具 举报

0

主题

1

帖子

18

积分

Newbie

Rank: 1

积分
18
发表于 2018-7-16 19:49:00 | 显示全部楼层
推!
已經在使用了
好用!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | Register Now

本版积分规则

 

GMT+8, 2018-8-15 19:34 , Processed in 0.082444 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表