局域网内双升游戏的设计(二)--系统框架
来源:互联网 发布:廖雪峰javascript下载 编辑:程序博客网 时间:2024/04/28 14:07
服务器客户端关系
一般来说,服务器与客户端在交流过程中,都会有自身的状态,也有很多逻辑的判断。这些可以放在服务器,也可以放在客户端。如果把功能分别放在两端的话,会造成逻辑比较混乱且不同步的现象。比如,在抢亮的过程中,可能有先后顺序,某个客户端亮主后,如果先在客户端上显示,但是消息到达服务器后,发现已经有人先亮了,就需要重新显示。这样一来,会造成逻辑的复杂化。在本程序中,采用的是服务器保存所有的状态,处理所有的逻辑。比如,客户端在点击亮主后,做的事情就是发一个消息给服务器,不做任何显示操作,等待服务器传来亮主的消息后再显示。出牌后,也是直接发消息给服务器,并等待服务器的计算结果后再显示出去的牌。客户端只会按照服务器命令做动作的。这样一直瘦客户端的形式,能很大程度上降低整个程序的复杂度。但是会增加消息数和服务器的负担。
ps:现在暂未实现掉线重连机制。
消息定义
在程序中,所有的消息采用字符串的形式封装,每个消息定义中有一个消息类型的字符串,还有这个消息包含的多个参数。主要定义如下:
typedef std::map<std::string, std::string> ParamMap; class SESSIONBASE_API CMsg{public: std::string& operator []( const std::string& key ) { return m_param[key]; } std::string& operator []( const char* key ) { return m_param[key]; }private: std::string m_type; ParamMap m_param;};
这样,可以很方便地设置或者获取某个消息的某个参数:
CMsg discardMsg;discardMsg.getType() = CMsgDef::MSGTYPE_TODISCARD;discardMsg[CMsgDef::COMMON_PARAM_INDEX] = ToString( pState->m_zhuangIndex );
将消息转换为一个流格式,于是,在CSessionBase的sendMsg中,通过调用m_pWrapper->wrapMsg( pMsg, m_sendBuffer, len );来将CMsg对象转换为一个可以发送的字符串序列。本程序中采用的是XML格式封装,即:m_pWrapper是一个CXmlMsgWrapper对象。如果希望改变封装格式或者对消息进行适当加密的话,可以新建一个CMsgWrapper的子类,并且实现wrapMsg和unWrapMsg两个函数即可。
服务器状态机
图 1. 服务器中类图
在服务器中,主要的类如上图所示,CShengjiGamerMgr是总的调度,所有用户的连接都是通过它来接受的,每当有新的一桌游戏开始时,就新建一个CShengjiGamer对象。每个CShengjiGamer对象中最多保存4个Session,分别代表4个不同的玩家。CShengjiGamer中还有一个CGamerStateBase,这是个状态机,使用了状态模式,不同的状态的逻辑处理不一样,要响应的消息也不一样。所以,每个状态机重载的时候要实现各自不同的消息处理函数。这样可以避免在不同状态下,收到客户端的错误消息(或者因为网络延时造成的超时消息)而导致的状态混乱。
状态切换时,要新建一个新的状态机,并且删除旧的状态机,类似代码如下:
if ( SHENGJI_PLAYER_COUNT == readyCount ) { CGamerStateBase* pNewState = new CCompetePointState( m_players, m_initingPlayers, m_pState ); delete this; return pNewState; }
在各个状态中,需要保存当前游戏的数据,就放在m_pState中。在每个状态间来回传递。
参考代码+编译后的程序:http://download.csdn.net/detail/hustxyj/7024091- 局域网内双升游戏的设计(二)--系统框架
- 局域网内双升游戏的设计
- 局域网内双升游戏的设计(一)--界面
- 局域网内双升游戏的设计(三)--算法
- 局域网系统设计的主要内容
- 局域网系统设计的主要内容
- 游戏UI框架设计(二)
- 游戏UI框架设计(二)
- 游戏UI框架设计(二)
- 游戏UI框架设计(二)
- 游戏UI框架设计(二)
- 游戏UI框架设计(二)
- 游戏UI框架设计(二)
- Unity3D UNET 模仿局域网游戏(二)
- MFC设计局域网对战五子棋游戏(二)实现GDI+自绘按钮
- 局域网实时通信系统的设计与实现(1)
- 局域网实时通信系统的设计与实现(2)
- 局域网实时通信系统的设计与实现(3)
- Isomap资料
- cocos2d-x初步
- 【ORACLE备份与恢复】用户管理的:基于时间的数据库不完全恢复
- Thread,Looper,Handler,Message,MessageQueue之间的关系
- maven中依赖注入的排斥
- 局域网内双升游戏的设计(二)--系统框架
- 内部排序总结(附各种排序算法源码)
- linux系统编程之信号(二):一些信号发送函数和不同精度的睡眠
- Hibernate反向工程步骤及DAO Type无法选择Spring DAO解决方法
- linux tcp定时器2
- 对xml字符串的操作
- Eclipse建working set
- 接受过去和现在的模样,才会有能量去追寻自己的未来。
- Android开发中遇到的问题(一)——自定义videoview设置视频大小,实现上下黑边