服务器公共组件实现 -- 状态机

原创 2007年09月24日 22:04:00

  有关State模式的设计意图及实现就不从设计模式中摘抄了,我们只来看看游戏服务器编程中如何使用State设计模式。

  首先还是从mangos的代码开始看起,我们注意到登录服在处理客户端发来的消息时用到了这样一个结构体:

  struct AuthHandler
  {
    eAuthCmd cmd;
    uint32 status;
    bool (AuthSocket::*handler)(void);
  };

  该结构体定义了每个消息码的处理函数及需要的状态标识,只有当前状态满足要求时才会调用指定的处理函数,否则这个消息码的出现是不合法的。这个status状态标识的定义是一个宏,有两种有效的标识,STATUS_CONNECTED和STATUS_AUTHED,也就是未认证通过和已认证通过。而这个状态标识的改变是在运行时进行的,确切的说是在收到某个消息并正确处理完后改变的。

  我们再来看看设计模式中对State模式的说明,其中关于State模式适用情况里有一条,当操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态,这个状态通常用一个或多个枚举变量表示。

  描述的情况与我们这里所要处理的情况是如此的相似,也许我们可以试一试。那再看看State模式提供的解决方案是怎样的,State模式将每一个条件分支放入一个独立的类中。

  由于这里的两个状态标识只区分出了两种状态,所以,我们仅需要两个独立的类,用以表示两种状态即可。然后,按照State模式的描述,我们还需要一个Context类,也就是状态机管理类,用以管理当前的状态类。稍作整理,大概的代码会类似这样:

  状态基类接口:
  StateBase
  {
    void Enter() = 0;
    void Leave() = 0;
    void Process(Message* msg) = 0;
  };

  状态机基类接口:
  MachineBase
  {
    void ChangeState(StateBase* state) = 0;

    StateBase* m_curState;
  };

  我们的逻辑处理类会从MachineBase派生,当取出数据包后交给当前状态处理,前面描述的两个状态类从StateBase派生,每个状态类只处理该状态标识下需要处理的消息。当要进行状态转换时,调用MachineBase的ChangeState()方法,显示地告诉状态机管理类自己要转到哪一个状态。所以,状态类内部需要保存状态机管理类的指针,这个可以在状态类初始化时传入。具体的实现细节就不做过多描述了。

  使用状态机虽然避免了复杂的判断语句,但也引入了新的麻烦。当我们在进行状态转换时,可能会需要将一些现场数据从老状态对象转移到新状态对象,这需要在定义接口时做一下考虑。如果不希望执行拷贝,那么这里公有的现场数据也可放到状态机类中,只是这样在使用时可能就不那么优雅了。

  正如同在设计模式中所描述的,所有的模式都是已有问题的另一种解决方案,也就是说这并不是唯一的解决方案。放到我们今天讨论的State模式中,就拿登录服所处理的两个状态来说,也许用mangos所采用的遍历处理函数的方法可能更简单,但当系统中的状态数量增多,状态标识也变多的时候,State模式就显得尤其重要了。

  比如在游戏服务器上玩家的状态管理,还有在实现NPC人工智能时的各种状态管理,这些就留作以后的专题吧。 

基于有限状态机的交互组件设计与实现

有限状态机(FSM)(维基百科)是设计和实现事件驱动程序内复杂行为组织原则的有力工具。早在2007年,IBM的工程师就提出在在JAVASCRIPT中使用有限状态机来实现组件的方法,原文地址如下:《Ja...
  • it_man
  • it_man
  • 2015年01月09日 15:18
  • 2278

Android的组件设计与状态机

状态机: 百度百科定义:包含一组状态集(states)、一个起始状态(start state)、一组输入符号集(alphabet)、 一个映射输入符号和当前状态到下一状态的转换函数(transit...

服务器架构设计3------状态机的使用

对于网络服务器,当有多个并发用户连接服务器,那服务器是如何同时处理这些用户请求呢,大体上可以分成3种方式 多线程、多进程,分别开启多个进程或线程单独处理每一个ses连接,往往短连接会采用这种...

有限状态机的c语言实现

  • 2015年10月26日 09:35
  • 2KB
  • 下载

服务器设计系列:状态机

一、状态机描述     状态机理论最初的发展在数字电路设计领域。在数字电路方面,根据输出是否与输入信号有关,状态机可以划分为Mealy型和Moore型状态机;根据输出是否与输入信号同步,状态机可以划分...

用状态机实现 ADC 控制电路

  • 2014年03月26日 09:49
  • 328KB
  • 下载

Mangos源码分析(9):服务器公共组件实现之环形缓冲区

消息队列锁调用太频繁的问题算是解决了,另一个让人有些苦恼的大概是这太多的内存分配和释放操作了。频繁的内存分配不但增加了系统开销,更使得内存碎片不断增多,非常不利于我们的服务器长期稳定运行。也许我们可以...

linux下状态机实现

  • 2017年08月29日 13:39
  • 4KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:服务器公共组件实现 -- 状态机
举报原因:
原因补充:

(最多只允许输入30个字)