一. libs/common部分
MemoryStream:
将常用数据类型二进制序列化与反序列化,内部封装了一个std::vector<uint8>
。使用方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14MemoryStream stream;
stream << (int64)100000000;
stream << (uint8)1;
stream << (uint8)32;
stream << "kbe";
stream.print_storage();
uint8 n, n1;
int64 x;
std::string a;
stream >> x;
stream >> n;
stream >> n1;
stream >> a;
printf("还原: %lld, %d, %d, %s", x, n, n1, a.c_str());
Tasks:
任务Task
的管理类,内部封装了std::vector<Task *>
,通过调用process()
来遍历所有Tash
的process()
虚函数。
TimersT<T>:
定时器管理类,内部用小顶堆管理所有的定时器。通过1
2TimerHandle add(TimeStamp startTime, TimeStamp interval,
TimerHandler* pHandler, void * pUser);
来新增一个定时器,返回的TimerHandle
是新增定时器的句柄,可以控制相应的定时器。用户需要继承TimerHandler
类,并重载1
virtual void handleTimeout(TimerHandle handle, void * pUser)
虚函数来实现定时器的回调。
内部预定义了两个TimersT<T>
类1
2typedef TimersT<uint32> Timers;
typedef TimersT<uint64> Timers64;
二. libs/network部分
Address:
封装了ip和port
Packet:
发送和接收的包的最小单位,继承自MemoryStream
。在发送的时候Packet
都是嵌套在Bundle
的内部来使用的。
TcpPacket:
代表一个收到的TCP包,继承自Packet
,这个包只是recv收到的字节流,并不是上层协议中的消息(Message)。
UDPPacket:
代表一个收到的UDP包,继承自Packet
,这个包只是recv收到的字节流,并不是上层协议中的消息(Message)。
Bundle:
代表要发送的包的集合,内部有std::vector<Packet*>
数组。内部的Packet
根据TCP和UDP不同,有不同的最大字节数限制。TCP的一个Packet
最多包含1460个字节,UDP是1472字节。也就是说序列化到Bundle
中的数据会自动分包的。
BundleBroadcast:
继承自Bundle
,可以方便的处理如:用UDP向局域网内广播某些信息,并处理收集相关信息。
EndPoint:
抽象一个Socket及其相关操作,隔离平台相关性。
FixedMessages:
从“server/messages_fixed_defaults.xml”中读入消息的定义,维护了一个消息名字到消息id的映射。
MessageHandlers:
每个MessageHandler
类对应一个消息的处理,通过重载下面的虚函数来处理:1
virtual void handle(Channel* pChannel, MemoryStream& s)
MessageHandlers
维护MessageID
-> MessageHandler
的映射。
在把MessageHandler
加入到MessageHandlers
时,如果是固定消息,那么MessageID
是从FixedMessages
中的设置中来的,否则就一个递增得到的(会避开固定消息的id)。
以Baseapp
为例,所有的消息都是用宏定义在baseapp_interface.h/cpp中的,每个消息需要实现一个MessageHandler
的子类和一个MessageArgs
的子类(用来处理消息的参数)。并且会创建相应的实例,添加到messageHandlers
(是Network::MessageHandlers的实例)中去。然后在这些子类的handle中又会去调用Baseapp
中的相同名字的方法,最后这个消息其实是在Baseapp
的同名方法中处理的。
PacketReceiver:
用来收Packet,收到后会转给PacketReader来处理。
PacketReader:
会利用MessageHandlers把包转成对应的Message,即相应的函数调用。
PacketSender:
用来发送Packet的。
Channel:
抽象一个Socket连接,每个EndPoint都有其对应的Channel,它代表和维护一个Socket连接,如缓冲Packet,统计连接状态等。
提供一个ProcessPackets(MsgHanders* handers)接口处理该Channel上所有待处理数据。
EventPoller:
用于注册和回调网络事件,具体的网络事件由其子类实现processPendingEvents产生,目前EventPoller有两个子类: EpollPoller和SelectorPoller,分别针对于Linux和Windows。
通过bool registerForRead(int fd, InputNotificationHandler * handler);注册套接字的可读事件,回调类需实现InputNotificationHandler接口。
EventDispatcher:
核心类,管理和分发所有事件,包括网络事件,定时器事件,任务队列,统计信息等等。
它包含 EventPoller Tasks Timers64 三个组件,在每次处理时,依次在这三个组件中取出事件或任务进行处理。Epoll的最小等待时间是到下一个timer的触发时间,最大等待时间目前是0.1秒。这样可以保证Timer能被精确的触发。
ListenerReceiver/PacketReceiver:
继承自InputNotificationHandler,分别用于处理监听套接字和客户端套接字的可读事件,通过bool registerReadFileDescriptor(int fd, InputNotificationHandler * handler); 注册可读事件。
NetworkInterface:
维护管理监听套接字,创建监听套接字对应的ListenerReceiver,并且通过一个EndPoint -> Channel的Map管理所有已连接套接字,提供一个processChannels(MsgHandlers* handers)接口处理所有Channel上的待处理数据。这一点上,有点像NGServer:ServiceManager。
网络部分的核心类结构图
各个组件之间的关系图