GateServer源码笔记
写了4个月php&nodejs之后,总算有机会能回去写C++服务器,而且是一直想从事的游戏服务器开发。找同事要了份服务端框架源码啃了起来,几个月没怎么写C++了,有些生疏,在此记录下源码阅读笔记。整个游戏服务器框架分为4个部分,basecode,gateserver,gameServer,dbproxy。其中basecode主要就是基础类对象,如日志、共享内存、socket等的封装。基本工作流程是客户端连接到gateServer,收发游戏数据;gateServer与gameServer通过两个共享内存对象进行双工通信,gameServer处理游戏逻辑通过dbproxy操作后台数据库;dbproxy连接数据库和gameServer,数据库采用的mysql。
gateServer实现上主要就是单线程的epoll,用类tcpctrl封装了下。初始化部分的工作主要是初始化日志、读取配置文件、注册处理信号函数、daemonlize、初始化epoll、创建通信的共享内存对象、写入pid文件。
gateServer在内存控制上在初始化阶段申请好,而不是动态的malloc、free,以便更好的控制内存。例如一个gateServer只服务一定数量的连接,比如20000,做法是采用数组进行存储,数组下标即为套接字描述符。数组存储对象为封装过的连接对象。在初始化阶段创建epoll对象,生成监听套接字并进行注册,设置监听套接字的SO_REUSEADDR、SO_KEEPLIVE、SO_LINGER、SO_SNDBUF等选项。
初始化完了,程序循环接受、处理消息,直到程序退出。处理的事件包括退出,即g_shutdown为true;重新载入配置;获取消息;检查是否有数据需要发送;检查超时套接字。退出时写入连接对象统计信息。获取消息主要是接收客户端的连接和数据,如果是监听套接字的事件则将accept返回的连接对象添加到连接对象数组,如果是其他则表示是客户端发来的数据,进行接收经过一定处理后写入管道。处理完新连接和数据接收,再检查是否有数据需要发送,即从共享内存中获取消息进行处理,发送给客户端,并关闭套接字重置连接对象数组中的相应对象,即客户端和GateServer采用短连接的方式进行通信,每次通信客户端建立连接、发送数据、接收数据然后连接断开,下一次通信时重新建立连接。需要处理的另一类事件是检查是否有超时,即检查当前时刻与连接对象时间戳是否超过阈值,超过则直接清理连接对象信息。