当前位置 : 145z游戏站 | 热血传奇 | 技术教程 | 

传奇服务端源码解析:初始化流程与多线程架构设计

热度:
服务端源码的入口函数位于GameSvr.cpp的WinMain。初始化阶段依次执行CheckAvailableIOCP检查操作系统是否支持IOCP模型,该检查针对NT内核的Windows系统。InitInstance完成界面初始化和WSAStartup网络库加载,随后InitApplication注册窗口回调函数MainWndProc。窗口回调函数负责处理系统消息与网络事件,是服务端与外部通信的中枢。

启动服务的过程从回调函数接收到IDM_STARTSERVICE命令开始。OnCommand创建一个名为InitializingServer的线程,该线程调用ConnectToServer函数。ConnectToServer将监听套接字注册到窗口回调,消息ID设定为_IDM_CLIENTSOCK_MSG,完成注册后连接自身服务器。这步操作建立起服务端内部通信的基础通道。注册完成后收到_IDM_CLIENTSOCK_MSG消息,窗口调用OnClientSockMsg函数,该函数内部创建多个核心处理线程,包括ProcessLogin和ProcessUserHuman等。

多线程架构设计以IOCP完成端口模型为核心。LoginGate作为登录网关服务器,监听7000端口接收客户端连接。客户端接入后,AcceptThread线程执行accept操作生成CSessionInfo对象存储客户端socket信息。新套接字通过CreateIoCompletionPort关联到完成端口,随后投递异步WSARecv调用。WSASend或WSARecv作为异步函数立即返回,实际数据收发由Windows系统在后台执行,完成后将结果发送至完成端口。GetQueuedCompletionStatus函数阻塞等待IO操作完成,从完成端口取出结果后继续投递下一轮IO操作。

LoginSvr服务器与LoginGate的通信机制建立在消息队列与心跳保持之上。LoginSvr的ServerWorkerThread线程循环调用GetQueuedCompletionStatus获取IO结果,通过pGateInfo->HasCompletionPacket验证消息格式。不同前缀字符对应不同处理分支:'-'表示发送心跳数据包到每个LoginGate服务器,'A'处理LoginGate转发的客户端消息并加入各网关消息队列,'O'处理网关accept客户端后的用户信息添加,'X'处理客户端socket关闭后的状态更新,'S'处理GameSvr发送的用户下线消息并更新数据库验证字段。

消息传递路径涵盖多层网关转发。LoginGate从客户端收到数据后经OnClientSockMsg的FD_READ事件读取,数据包压入g_xMsgQueue队列。ThreadFuncForMsg线程检测队列中的数据包,通过IOCP投递WSASend发送到LoginSvr。LoginSvr处理完成后将结果发送回LoginGate,再由LoginGate转发给客户端。网关间通信通过定时器维持心跳连接,OnTimerProc定时调用SendExToServer发送PACKET_KEEPALIVE心跳包。连接断开时设置_ID_TIMER_CONNECTSERVER定时器尝试重连。

服务端源码由七个工程文件组成:AdminCmd、DBSrv、GameGate、GameSvr、LoginGate、LoginSvr、SelGate。GameSvr承载游戏主逻辑与地图处理,DBSrv处理数据库读写操作,SelGate负责角色选择网关。客户端源码分为WindHorn和Mir2Ex两个工程。整个架构具备多层网关转发、IOCP异步IO、多线程并发处理三大特征,各层之间通过自定义协议包格式进行通信。
[顶部]