http://blog.csdn.net/xiaozhi0999/article/details/51326200
Ue4 implementation of RPC, or relatively useful, the following simple analysis of the implementation of the UE4 network.
The class of the main processing network in UE4 is Unetdriver, and the Unetdriver class has the following two members
class UNetConnection* ServerConnection;
TArray<class UNetConnection*> ClientConnections;
You can see from the name that serverconnection represents the connection that the client makes to the server, and Clientconnections is the connection to the client that the server holds.
Ue4 is implemented by Uactorchannel to synchronize the actor between the server and the client, where each actor that needs to be synchronized between the server and the client is associated with a uactorchannel. We look at Unetconnection's code to verify this.
TMap<TWeakObjectPtr<AActor>,class UActorChannel*> ActorChannels;
See the implementation of Uactorchannel, there are several important member functions
Send data:
virtual FPacketIdRange SendBunch(FOutBunch* Bunch, bool Merge);
int32 SendRawBunch(FOutBunch* Bunch, bool Merge);
Receive data:
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 );
In the case of sending data, the Sendrawbunch implementation in Uactorchannel or the corresponding function in unetconnection is called, whereas in Unetconnection, the following member variable
Fbitwriter Sendbuffer;
That is, send buffer, the main function of Sendrawbunch is to assign data from Foutbunch to Sendbuffer, and then call Unetconnection Lowlevelsend interface to send data, of course, At the end of the call, the send buffer of the socket is called.
PS: The above discussion is for simplification, ignoring the hierarchy of classes (for example: Uipconnection derived from unetconnection, so some functions are implemented in uipconnection)
Let's examine the RPC process in detail.
When invoking a remote function, mainly in the unetdriver of the Internalprocessremotefunction function, first based on the call actor to find the corresponding Uactorchannel, the code is as follows:
uactorchannel* Ch = Connection->actorchannels.findref (Actor);
If it is not found, you need to create a uactorchannel, as follows:
Ch = (Uactorchannel *) Connection->createchannel (chtype_actor, 1);
Note that the Chindex is the main way to differentiate between actors, so you need to assign different chindex for each uactorchannel, which is implemented in CreateChannel, when the third argument is not passed, as in the above code, The first available Chindex is found, as shown in the following code:
// Search the channel array for an available location
for( ChIndex=FirstChannel; ChIndex<MAX_CHANNELS; ChIndex++ )
{
if( !Channels[ChIndex] )
{
break;
}
}