内容纲要

一. network 部分

EndPoint:

抽象一个 Socket 及其相关操作,隔离平台相关性。

TcpPacket:

代表一个 TCP 包,这个包只是 recv 收到的字节流,并不是上层协议中的消息 (Message)。

MsgHandlers:

每个 MessageHandler 类对应一个消息的处理。MsgHanders 维护 MsgId -> MsgHandler 的映射。

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 三个组件,在每次处理时,依次在这三个组件中取出事件或任务进行处理。

ListenerReceiver/PacketReceiver:

继承自 InputNotificationHandler,分别用于处理监听套接字和客户端套接字的可读事件,通过 bool registerReadFileDescriptor(int fd, InputNotificationHandler * handler); 注册可读事件。

NetworkInterface:

维护管理监听套接字,创建监听套接字对应的 ListenerReceiver,并且通过一个 EndPoint -> Channel 的 Map 管理所有已连接套接字,提供一个 processChannels(MsgHandlers* handers) 接口处理所有 Channel 上的待处理数据。这一点上,有点像 NGServer:ServiceManager。

二. LoginApp 启动流程

main:

所有 App 都有一致的 main 函数,生成组件唯一 ID,读取配置等,转到 kbeMainT

kbeMainT:

  1. 生成公钥私钥,调试相关初始化
  2. 创建单例 EventDispatcher 和 NetworkInterface
  3. 创建 LoginApp,并传入 EventDispatcher 和 NetworkInterface
  4. 调用 LoginApp:run()

LoginApp:run():

调用基类 ServerApp:run(),后者调用 EventDispatcher:processUntilBreak() 开始处理各种事件

LoginAppInterface:

存放和注册 LoginApp 响应的所有消息的消息回调,参见 loginapp_interface.h。
通过 LoginAppInterface::messageHandlers 即可导出消息处理类

细节流程:

  1. NetworkInterface 构造函数中,创建 ListenSocket 和 ListenerReceiver,注册到 EventDispatcher
  2. 当有新连接到达时,EventDispatcher 触发 ListenerReceiver:handleInputNotification
  3. handleInputNotification 创建新套接字的 Channel,并将 Channel 注册到 NetworkInterface
  4. 新 Channel 初始化时,创建新套接字对应的 PacketReceiver,并注册到 EventDispatcher
  5. 在 LoginApp::initializeEnd 中,添加了一个 TIMEOUT_CHECK_STATUS Timer 该 Timer 触发时,会最终调用 networkInterface().processChannels() 处理各 Channel 的消息,目前该 Timer 是 20mss

发表评论

电子邮件地址不会被公开。 必填项已用*标注