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