加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 业界 > 正文

教你从新写游戏处事器框架

发布时间:2019-02-21 01:04:05 所属栏目:业界 来源:腾讯游戏学院
导读:1.需求 因为越通用的代码,就是越没用的代码,以是在计划之初,我就以为应该行使分层的模式来构建整个体系。凭证游戏处事器的一样平常需求分别,最根基的可以分为两层: 底层基本成果:包罗通讯、耐久化等很是通用的部门,存眷的是机能、易用性、扩展性等指标

在协议层面,最根基的需求有“分包”“分发”“工具序列化”等几种需求。假如要支持“哀求-相应”模式,还必要在协议中带上“序列号”的数据,以便对应“哀求”和“相应”。其它,游戏凡是都是一种“会话”式的应用,也就是一系列的哀求,会被视为一次“会话”,这就必要协众必要有相同 Session ID 这种数据。为了满意这些需求,计一律个条理为:Protocol。

拥有了以上两个条理,是可以完成最根基的协议层手段了。可是,我们每每但愿营业数据的协议包,能自动化的成为编程中的工具,以是在处理赏罚动静体这里,必要一个可选的特殊条理,用来把字节数组,转换成工具。以是我计划了一个出格的处理赏罚器:ObjectProcessor ,去类型通讯模块中工具序列化、反序列化的接口。

Transport

此条理是为了同一各类差异的底层传输协议而配置的,最根基应该支持 TCP 和 UDP 这两种协议。对付通讯协议的抽象,着实在许多底层库也做的很是好了,好比 Linux 的 socket 库,其读写 API 乃至可以和文件的读写通用。C# 的 Socket 库在 TCP 和 UDP 之间,其 API 也险些是完全一样的。可是因为浸染游戏处事器,许多时辰还会接入一些出格的“接入层”,好比一些署理处事器,可能一些动静中间件,这些 API 然则八门五花的。其它,在 html5 游戏(好比微信小游戏)和一些页游规模,尚有效 HTTP 处事器作为游戏处事器的传统(如行使 WebSocket 协议),这样就必要一个完全差异的传输层了。

处事器传输层在异步模子下的根基行使序列:

  1. 在主轮回中,不绝实行读取有什么数据可读
  2. 假如上一步返回稀有据达到了,则读取数据
  3. 读取数据处理赏罚后,必要发送数据,则向收集写入数据

按照上面三个特点,可以归纳出一个根基接口:

  1. class Transport { 
  2. public:    
  3.    /** 
  4.     * 初始化Transport工具,输入Config工具设置最大毗连数等参数,可所以一个新建的Config工具。 
  5.     */    
  6.    virtual int Init(Config* config) = 0; 
  7.  
  8.    /** 
  9.     * 搜查是否稀有据可以读取,返回可读的变乱数。后续代码应该按照此返回值轮回挪用Read()提取数据。 
  10.     * 参数fds用于返回呈现变乱的全部fd列表,len暗示这个列表的最大长度。假如可用变乱大于这个数字,并不影响后续可以Read()的次数。 
  11.     * fds的内容,假如呈现负数,暗示有一个新的终端守候接入。 
  12.     */ 
  13.    virtual int Peek(int* fds, int len) = 0; 
  14.  
  15.    /** 
  16.     * 读取收集管道中的数据。数据放在输出参数 peer 的缓冲区中。 
  17.     * @param peer 参数是发闹变乱的通讯对端工具。 
  18.     * @return 返回值为可读数据的长度,假如是 0 暗示没稀有据可以读,返回 -1 暗示毗连必要被封锁。 
  19.     */ 
  20.    virtual int Read( Peer* peer) = 0; 
  21.  
  22.    /** 
  23.     * 写入数据,output_buf, buf_len为想要写入的数据缓冲区,output_peer为方针队端, 
  24.     * 返回值暗示乐成写入了的数据长度。-1暗示写入堕落。 
  25.     */ 
  26.    virtual int Write(const char* output_buf, int buf_len, const Peer& output_peer) = 0; 
  27.  
  28.    /** 
  29.     * 封锁一个对端的毗连 
  30.     */ 
  31.    virtual void ClosePeer(const Peer& peer) = 0; 
  32.  
  33.    /** 
  34.     * 封锁Transport工具。 
  35.     */ 
  36.    virtual void Close() = 0; 
  37.  

在上面的界说中,可以看到必要有一个 Peer 范例。这个范例是为了代表通讯的客户端(对端)工具。在一样平常的 Linux 体系中,一样平常我们用 fd (File Description)来代表。可是由于在框架中,我们还必要为每个客户端成立吸取数据的缓存区,以及记录通讯地点等成果,以是在 fd 的基本上封装了一个这样的范例。这样也有利于把 UDP 通讯以差异客户端的模子,举办封装。

  1. ///@brief 此范例认真存放毗连过来的客户端信息和数据缓冲区 
  2. class Peer { 
  3. public: 
  4.     int buf_size_;      ///< 缓冲区长度 
  5.     char* const buffer_;///< 缓冲区起始地点 
  6.     int produced_pos_;  ///< 填入了数据的长度 
  7.     int consumed_pos_;  ///< 耗损了数据的长度 
  8.  
  9.     int GetFd() const; 
  10.     void SetFd(int fd);    /// 获适合地地点 
  11.     const struct sockaddr_in& GetLocalAddr() const; 
  12.     void SetLocalAddr(const struct sockaddr_in& localAddr);    /// 得到长途地点 
  13.  
  14.     const struct sockaddr_in& GetRemoteAddr() const; 
  15.     void SetRemoteAddr(const struct sockaddr_in& remoteAddr); 
  16.  
  17. private: 
  18.     int fd_;                            ///< 收发数据用的fd 
  19.     struct sockaddr_in remote_addr_;    ///< 对端地点 
  20.     struct sockaddr_in local_addr_;     ///< 本端地点 
  21. }; 

(编辑:湖南网)

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

热点阅读