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

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

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

游戏使用 UDP 协议的特点:一般来说 UDP 是无连接的,但是对于游戏来说,是肯定需要有明确的客户端的,所以就不能简单用一个 UDP socket 的fd 来代表客户端,这就造成了上层的代码无法简单在 UDP 和 TCP 之间保持一致。因此这里使用 Peer 这个抽象层,正好可以解决这个问题。这也可以用于那些使用某种消息队列中间件的情况,因为可能这些中间件,也是多路复用一个 fd 的,甚至可能就不是通过使用 fd 的 API 来开发的。

对于上面的 Transport 定义,对于 TCP 的实现者来说,是非常容易能完成的。但是对于 UDP 的实现者来说,则需要考虑如何充分利用 Peer ,特别是 Peer.fd_ 这个数据。我在实现的时候,使用了一套虚拟的 fd 机制,通过一个客户端的 IPv4 地址到 int 的对应 Map ,来对上层提供区分客户端的功能。在 Linux 上,这些 IO 都可以使用 epoll 库来实现,在 Peek() 函数中读取 IO 事件,在 Read()/Write() 填上 socket 的调用就可以了。

另外,为了实现服务器之间的通信,还需要设计和 Tansport 对应的一个类型:Connector 。这个抽象基类,用于以客户端模型对服务器发起请求。其设计和 Transport 大同小异。除了 Linux 环境下的 Connecotr ,我还实现了在 C# 下的代码,以便用 Unity 开发的客户端可以方便的使用。由于 .NET 本身就支持异步模型,所以其实现也不费太多功夫。

  1. /** 
  2.  * @brief 客户端使用的连接器类,代表传输协议,如 TCP 或 UDP 
  3.  */ 
  4. class Connector { 
  5.  
  6. public:    virtual ~Connector() {}     
  7.   
  8.     /** 
  9.      * @brief 初始化建立连接等 
  10.      * @param config 需要的配置 
  11.      * @return 0 为成功 
  12.      */ 
  13.     virtual int Init(Config* config) = 0; 
  14.  
  15.     /** 
  16.      * @brief 关闭 
  17.      */ 
  18.     virtual void Close() = 0; 
  19.  
  20.     /** 
  21.      * @brief 读取是否有网络数据到来 
  22.      * 读取有无数据到来,返回值为可读事件的数量,通常为1 
  23.      * 如果为0表示没有数据可以读取。 
  24.      * 如果返回 -1 表示出现网络错误,需要关闭此连接。 
  25.      * 如果返回 -2 表示此连接成功连上对端。 
  26.      * @return 网络数据的情况 
  27.      */ 
  28.     virtual int Peek() = 0; 
  29.  
  30.     /** 
  31.      * @brief 读取网络数  
  32.      * 读取连接里面的数据,返回读取到的字节数,如果返回0表示没有数据, 
  33.      * 如果buffer_length是0, 也会返回0, 
  34.      * @return 返回-1表示连接需要关闭(各种出错也返回0) 
  35.      */ 
  36.     virtual int Read(char* ouput_buffer, int buffer_length) = 0; 
  37.  
  38.     /** 
  39.      * @brief 把input_buffer里的数据写入网络连接,返回写入的字节数。 
  40.      * @return 如果返回-1表示写入出错,需要关闭此连接。 
  41.      */ 
  42.    virtual int Write(const char* input_buffer, int buffer_length) = 0; 
  43.  
  44. protected: 
  45.     Connector(){} 
  46. }; 

Protocol

(编辑:温州站长网)

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

热点阅读