http://blog.csdn.net/xiaozhi0999/article/details/51326200
ue4實現了rpc,還是比較好用的,下面簡單分析一下ue4網路部分的實現。
ue4中主要處理網路的類是UNetDriver, UNetDriver類中有如下兩個成員
[cpp] view plain copy print ? class UNetConnection* ServerConnection; TArray<class UNetConnection*> ClientConnections;
從名字就能看出ServerConnection代表了用戶端向伺服器建立的串連,而ClientConnections是伺服器持有的用戶端的串連。
ue4是通過UActorChannel來實現Actor在伺服器和用戶端之間同步的,其中每個需要在伺服器和用戶端之間同步的actor都會關聯一個UActorChannel,我們看UNetConnection的代碼可以驗證這一點
[cpp] view plain copy print ? TMap<TWeakObjectPtr<AActor>,class UActorChannel*> ActorChannels;
看UActorChannel的實現,有如下幾個重要的成員函數
發送資料:
[cpp] view plain copy print ? virtual FPacketIdRange SendBunch(FOutBunch* Bunch, bool Merge); int32 SendRawBunch(FOutBunch* Bunch, bool Merge);
接收資料:
[cpp] view plain copy print ? virtual void ReceivedBunch( FInBunch& Bunch ) PURE_VIRTUAL(UChannel::ReceivedBunch,); bool ReceivedNextBunch( FInBunch & Bunch, bool & bOutSkipAck ); void ReceivedRawBunch( FInBunch & Bunch, bool & bOutSkipAck ); bool ReceivedSequencedBunch( FInBunch& Bunch );
拿發送資料來說,UActorChannel中SendRawBunch實現還是調用UNetConnection中相應的函數,而在UNetConnection中,有如下成員變數
[cpp] view plain copy print ? FBitWriter SendBuffer; 即發送緩衝區,SendRawBunch的主要作用就是把資料從FOutBunch中賦值到SendBuffer上,然後調用UNetConnection的LowLevelSend介面發送資料,當然,到最後還是調用Socket的Send函數發送緩衝區。
ps:以上討論為了簡化,忽略了類的層次(比如:UIpConnection從UNetConnection派生,所以有些函數具體實現是在UIpConnection中)
下面我們來具體分析一下rpc過程
當調用一個遠端函數的時候,主要是在UNetDriver的InternalProcessRemoteFunction函數中處理的,先根據調用Actor來尋找對應的UActorChannel,代碼如下:
[cpp] view plain copy print ? UActorChannel* Ch = Connection->ActorChannels.FindRef(Actor);
如果沒有找到,則需要建立一個UActorChannel,如下:
[cpp] view plain copy print ? Ch = (UActorChannel *)Connection->CreateChannel( CHTYPE_Actor, 1 );
注意, 對端主要是通過ChIndex來區分不同的Actor,所以需要為每個UActorChannel分配不同的ChIndex,這個過程是在CreateChannel中實現的,當不傳遞第三個參數的時候,如上邊代碼那樣,會找到第一個可用的ChIndex,如下代碼所示:
[cpp] view plain copy print ?