加入收藏 | 设为首页 | 会员中心 | 我要投稿 晋中站长网 (https://www.0354zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

教你从头写游戏服务器框架

发布时间:2019-02-20 22:44:34 所属栏目:外闻 来源:腾讯游戏学院
导读:1.需求 由于越通用的代码,就是越没用的代码,所以在设计之初,我就认为应该使用分层的模式来构建整个系统。按照游戏服务器的一般需求划分,最基本的可以分为两层: 底层基础功能:包括通信、持久化等非常通用的部分,关注的是性能、易用性、扩展性等指标

设计完 Transport/Protocol/Processor 三个通信处理层次后,就需要一个组合这三个层次的代码,那就是 Server 类。这个类在 Init() 的时候,需要上面三个类型的子类作为参数,以组合成不同功能的服务器,如:

  1. TlvProtocol tlv_protocol;   //  Type Length Value 格式分包协议,需要和客户端一致 
  2. TcpTransport tcp_transport; // 使用 TCP 的通信协议,默认监听 0.0.0.0:6666 
  3. EchoProcessor echo_processor;   // 业务逻辑处理器 
  4. Server server;  // DenOS 的网络服务器主对象 
  5. server.Init(&tcp_transport, &tlv_protocol, &echo_processor);    // 组装一个游戏服务器对象:TLV 编码、TCP 通信和回音服务 

Server 类型还需要一个 Update() 函数,让用户进程的“主循环”不停的调用,用来驱动整个程序的运行。这个 Update() 函数的内容非常明确:

  1. 检查网络是否有数据需要处理(通过 Transport 对象)
  2. 有数据的话就进行解码处理(通过 Protocol 对象)
  3. 解码成功后进行业务逻辑的分发调用(通过 Processor 对象)

另外,Server 还需要处理一些额外的功能,比如维护一个会话缓存池(Session),提供发送 Response 和 Notice 消息的接口。当这些工作都完成后,整套系统已经可以用来作为一个比较“通用”的网络消息服务器框架存在了。剩下的就是添加各种 Transport/Protocol/Processor 子类的工作。

  1. class Server { 
  2.  
  3. public: 
  4.     Server(); 
  5.     virtual ~Server(); 
  6.   
  7.     /** 
  8.      * 初始化服务器,需要选择组装你的通信协议链 
  9.      */ 
  10.     int Init(Transport* transport, Protocol* protocol, Processor* processor, Config* config = NULL); 
  11.  
  12.     /** 
  13.      * 阻塞方法,进入主循环。 
  14.      */ 
  15.     void Start(); 
  16.  
  17.     /** 
  18.      * 需要循环调用驱动的方法。如果返回值是0表示空闲。其他返回值表示处理过的任务数。 
  19.      */ 
  20.     virtual int Update(); 
  21.     void ClosePeer(Peer* peer, bool is_clear = false); //关闭当个连接,is_clear 表示是否最终整体清理 
  22.  
  23.     /** 
  24.      * 关闭服务器 
  25.      */ 
  26.     void Close(); 
  27.  
  28.     /** 
  29.      * 对某个客户端发送通知消息, 
  30.      * 参数peer代表要通知的对端。 
  31.      */ 
  32.     int Inform(const Notice& notice, const Peer& peer); 
  33.  
  34.     /** 
  35.      * 对某个  Session ID 对应的客户端发送通知消息,返回 0 表示可以发送,其他值为发送失败。 
  36.      * 此接口能支持断线重连,只要客户端已经成功连接,并使用旧的 Session ID,同样有效。 
  37.      */ 
  38.     int Inform(const Notice& notice, const std::string& session_id); 
  39.  
  40.     /** 
  41.      * 对某个客户端发来的Request发回回应消息。 
  42.      * 参数response的成员seqid必须正确填写,才能正确回应。 
  43.      * 返回0成功,其它值(-1)表示失败。 
  44.      */ 
  45.     int Reply(Response* response, const Peer& peer); 
  46.  
  47.     /** 
  48.      * 对某个 Session ID 对应的客户端发送回应消息。 
  49.      * 参数 response 的 seqid 成员系统会自动填写会话中记录的数值。 
  50.      * 此接口能支持断线重连,只要客户端已经成功连接,并使用旧的 Session ID,同样有效。 
  51.      * 返回0成功,其它值(-1)表示失败。 
  52.      */ 
  53.     int Reply(Response* response, const std::string& session_id); 
  54.  
  55.     /** 
  56.      * 会话功能 
  57.      */ 
  58.     Session* GetSession(const std::string& session_id = "", bool use_this_id = false); 
  59.     Session* GetSessionByNumId(int session_id = 0); 
  60.     bool IsExist(const std::string& session_id); 
  61.     
  62. }; 

(编辑:晋中站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读