站务联系

从零开始写一个简单好用的游戏服务器引擎[3] - 网络

发布时间:2021-04-17   来源:网络整理    
字号:

写网路模块的时侯比较了这些方案,最后选择了libevent.主要出于以下几点:

1.比较轻量.而且源代码也比较容易读懂,遇上了哪些不理解的做法游戏服务器,看看他的代码能很快明白原理.我认为这点非常重要.作为服务端我感觉在代码层面上尽量不要用自己不能完整驾御的东西.原先也想用boost::asio,但这个就属于我觉得自己短时间不能完整驾御.万一有哪些点上没有理解创作者的意图用错了,又没办法从源码里理解,风险就大了.

2.和其它模块耦合度低.这一点只是我最终舍弃boost::asio的成因之一.因为asio里关联使用了很多boost的其它工具.如果用asio要把这些boost的东西引用过来.增加了出错的风险跟维护的难度.

关于libevent,官方文档还是十分齐备的.

我把它封装成了我想要的方式.

主要有以下几个部份:

网络基础模块:SocketBase(定义插口.负责libevent自己的callback处理再通过插口还给详细泛型处理详细网路收发逻辑)

网络句柄:SocketThread(管理一个独立的句柄,开启一个新的libevent核心对象,用来调度一个网路模块)

服务端模块:Server(定义服务端插口,实现争创一个服务端还要的逻辑)

连接者模块:Connector(继承于SocketBase,用于跟服务端模块配合.在服务端模块Accept了一个新的连结的时侯争创一个连接者例子拿来管理连接者相关的信息从而于跟相应的连接者通信.)

客户端模块:Client(继承于SocketBase游戏服务器,因为有时服务端也须要作为客户端主动去Connect一个目标,所以要有客户端模块,典型的如网段服务器,Listen玩家接入的同时,也要Connect至不同的逻辑服务器起来作转发.定义客户端插口,实现争创一个客户端还要的逻辑.其中客户端分为独立句柄客户端跟共享句柄客户端.区别是独立句柄客户端是每一个客户端例子自己独霸一个句柄,用于单个客户端吞吐量大,但不会经常大量争创的场景.共享句柄客户端是所有客户端例子都共用一个句柄,通过一个管理者句柄管理.适用于客户端例子还要经常争创收缴或大量争创的场景)

主要就是这样.所以定义好以后结构大致是这么的:

// 网络基础模块
class ISocketBase
{
    ...
}
// 网络线程
class ISocketThread
{
    ...
}
// 服务端模块
class CSocketServer : public ISocketThread
{
    ...
}
// 连接者模块
class CSocketConnector : public ISocketBase
{
    ...
}
// 客户端模块
// * 独立客户端模块
class CSocketClient : public ISocketBase,public ISocketThread
{
    ...
}
// * 共享客户端模块
class CSocketMutiClient : public ISocketBase
{
    ...
}
// * 共享客户端模块管理者
class CSocketMutiClientMgr : public ISocketThread
{
    ...
}

嗯,大致结构跟承继关系就是那样了.

其中每一个ISocketThread就会管理一个event_base表针,作为一个风波循环去处理一个独立的网路风波(比如一个服务端窃听跟收发,一个/一组客户端连结跟收发).这样在高并发的状况下可以最大程度的榨取cpu的资源,使其才能承载更多的并发.

图说天下

×
二维码生成