UE3客户端加入DS过程
拉起DS進程
客戶端將比賽地圖及相關(guān)參數(shù)發(fā)送給ZoneSvr請求開賽,收到消息后,ZoneSvr會分配一個ip和端口號,并與客戶端發(fā)過來的地圖及其他參數(shù),來構(gòu)建一個命令行來拉起一個DS進程,
DS啟動時在UGameEngine::Init ==> UGameEngine::Browse中調(diào)用UGameEngine::LoadMap來序列化地圖數(shù)據(jù)到UWorld* GWorld,
并調(diào)用UWorld::SetGameInfo來創(chuàng)建AGameInfo對象,然后調(diào)用UWorld::Listen來創(chuàng)建UNetDriver* NetDriver,并調(diào)用UTcpNetDriver::InitListen來創(chuàng)建socket,
在LoadMap結(jié)尾發(fā)送一個信號量通知ZoneSvr,要ZoneSvr將ip和端口號發(fā)送給客戶端,告訴客戶端自己已經(jīng)準備好了
最后DS在UWorld::Tick中每幀調(diào)用NetDriver的UTcpNetDriver::TickDispatch函數(shù)中檢查是否有客戶端連接過來
客戶端加入DS
客戶端得到DS的ip和端口后,執(zhí)行命令:open 10.123.102.132:7500?Uin=5897623?Name=Tom?Team=0?ClanName=?SpectatorOnly=0?bVIP=0?bIsRoomOwner=0
open命令會調(diào)用UGameEngine::SetClientTravel函數(shù)將open命令參數(shù)內(nèi)容設(shè)置給UGameEngine的TravelURL變量
客戶端在游戲主循環(huán)UGameEngine::Tick中會每幀檢查UGameEngine的TravelURL變量是否為空
當不為空時,會調(diào)用UGameEngine::Browse來創(chuàng)建UNetPendingLevel類型的全局指針變量GPendingLevel
GPendingLevel在其構(gòu)造函數(shù)中創(chuàng)建UTcpNetDriver對象,然后調(diào)用該對象的InitConnect函數(shù)來創(chuàng)建UDP的Socket、UTcpipConnection對象及Control Channel
然后客戶端就正式開啟了加入DS的過程,詳細如下圖所示
?
Step2補充說明:
Ds在UWorld::Tick中每幀調(diào)用NetDriver的UTcpNetDriver::TickDispatch函數(shù)會先在ClientConnections數(shù)組中查找是否已經(jīng)創(chuàng)建了這個客戶端的連接,
發(fā)現(xiàn)沒有會調(diào)用UTcpipConnection::InitConnection來創(chuàng)建一個新的NetConnection,然后加入到ClientConnections數(shù)組中,
然后使用這個新的NetConnection調(diào)用ReceivedRawPacket來處理網(wǎng)絡(luò)包數(shù)據(jù),由于NMT_Hello包使用的是ControlChanel發(fā)送的,
而當前NetConnection的Channels數(shù)組中沒有該Chanel,于是會調(diào)用UNetConnection::CreateChannel創(chuàng)建ControlChanel,
然后使用新的ControlChanel調(diào)用UChannel::ReceivedRawBunch ==> UChannel::ReceivedSequencedBunch ==> UControlChannel::ReceivedBunch ==> UWorld::NotifyControlMessage來做出應(yīng)答
Step5補充說明:
bSuccessfullyConnected為true,并有了URL.Map及游戲模式,使得UGameEngine::Tick中檢查通過開始LoadMap加載客戶端地圖:
① 加載失敗,則調(diào)用傳入?failed參數(shù)調(diào)用UGameEngine::Browse來關(guān)閉UNetPendingLevel連接并將GPendingLevel置NULL(在UGameEngine::CancelPending函數(shù)中實現(xiàn)),然后加載缺省地圖(如大廳地圖)
② 加載成功,在LoadMap函數(shù)中會將GPendingLevel的NetDriver、NetConnection、ControlChannel轉(zhuǎn)交給新地圖的GWorld,地圖加載完成后會發(fā)送NMT_JOIN消息,并將GPendingLevel置NULL
其他說明:
a. UE3通過FSocketSubsystem類型封裝了windows(FSocketSubsystemWindows)和unix(FSocketSubsystemBSD)上的Socket,向上對引擎提供了一致的編程接口
? ? 引擎通過提供全局變量FSocketSubsystem* GSocketSubsystem單例的方式來使用Socket相關(guān)功能
b. 服務(wù)器的收包邏輯在UWorld::NotifyControlMessage函數(shù)的else分支中,客戶端的收包邏輯在UNetPendingLevel::NotifyControlMessage函數(shù)中
總結(jié)
以上是生活随笔為你收集整理的UE3客户端加入DS过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Perhaps you are runn
- 下一篇: 基础数学问题