UNetDriver
- 管理UNetConnections,并在UNetConnection之间共享数据。
- UNetDriver::TickDispatch负责接收网络数据
- RPC相关在这里处理。UNetDriver::ProcessRemoteFunction()\UNetDriver::ProcessRemoteFunctionForChannel()
- 在UNetDriver::TickDispatch中接收网络数据,通过UNetConnection::ReceivedRawPacket将数据包传递到对应的连接中.(如果NetConnection不存在,则进行Handshaking)
UIpNetDriver
- 负责标准网络连接
- ISocketSubsystem::GetLocalBindAddr\ISocketSubsystem::BindNextPort确定我们将绑定的IP和端口
UDemoNetDriver
- 负责录制回放。
UWebSocketNetDriver
USteamSocketsNetDriver
UBeaconNetDriver
UNetConnection
- 表示连接到游戏(网络)的单个客户端
- 从网络接收的数据包,并将数据包传递给适当的NetConnection(必要时建立新的NetConnection),本身不对数据包做处理
- 每个Connection有自己的一组Channel
- 包含(重新)建立连接逻辑,
UIpConnection
- 标准连接
USimulateClientNetConnection
UChildConnection
UDemoNetConnection
USteamSocketsNetDriverConnection
UWebSocketsNetConnection
UChannel
- 通道类型
UControlChannel
- 用于发送有关连接状态的信息(连接是否应关闭等)
UVoiceChannel
- 用于在客户端和服务器之间发送语音数据
UUniqueActorChannel
- A Unique Actor Channel will exist for every Actor replicated from the server to the client.
UActorChannel
- 交换角色及其子对象的属性和RPC的通道。
- ActorChannel管理复制的actor的创建和生存期
- 属性和RPC的实际复制实际上发生在FObjectReplicator中
UUnitTestChannel
UPendingNetGame
Handshaking
- Game Handshaking相关消息在DataChannel.h中定义
Server
- 服务端LoadMap时调用UWorld::Listen创建网络驱动程序、解析设置、UNetDriver::InitListen()
- ③ UWorld::NotifyControlMessage接收NMT_HELLO, 发送NMT_Challenger
- ⑤ UWorld::NotifyControlMessage接收NMT_Login验证质询数据,调用AGameModeBase::PreLogin->UWorld::WelcomPlayer->AGameModeBase::GameWelcomePlayer,发送包含地图信息的(NMT_Welcome),如果连接异常可在此拒绝连接(如参数错误等)
- ⑦ UWorld::NotifyControlMessage接收NMT_NetSpeed,并适当调正连接的Net Speed
Client
- ① 客户端在UEngine::Browse中建立一个新的UPendingNetGame(Initialize\InitNetDriver)
- ② 连接建立后调用UPendingNetGame::SendIinitialJoin(NMT_HELLO)开始Game Handshaking
- ④ UPendingNetGame::NotifyControlMessage接收NMT_Challenger,回复NMT_Login
- ⑥ UPendingNetGame::NotifyControlMessage接收NMT_Welcome,读取地图信息(start loading later),发送NMT_NetSpeed消息
数据类
FClassNetCache
- FClassNetCache::GetClassNetCache
- FClassNetCache::GetFromField
FFieldNetCache
UPackageMap
FNetBitWriter
FOutBunch
RPC
- 同步条件宏展开
DOREPLIFETIME_CONDITION(c,v,cond) { FDoRepLifetimeParams LocalDoRepParams; LocalDoRepParams.Condition = cond; size_t size = ((void)sizeof(UE4Asserts_Private::GetMemberNameCheckedJunk(((c*)0)->MemberName)), FName(TEXT(#v))); //方便阅读, 加了个变量传到下面的参数中. UProperty* ReplicatedProperty = GetReplicatedProperty(StaticClass(), c::StaticClass(), size); RegisterReplicatedLifetimeProperty(ReplicatedProperty, OutLifetimeProps, params); }
- 复制条件和其他一些东西 官网有资料.不整理了.
Client RPC to Server
- 客户端调用Server_RPC
- That request is forwarded (via NetDriver and NetConnection) to the Actor Channel that owns the Actor on which the RPC was called.
- Actor Channel将RPC标识符和参数序列化成Bunch,Bunch将包含Actor Channel的ID
- Actor Channel请求NetConnection发送该Bunch
- NetConnection把数据组装成Packet发送给服务器
- Server: NetDriver接收数据,并检查数据包地址,移交给适当的NetConnection.
- Server: NetConnection将Packet拆分成Bunch,并通过Bunch上的ID找到相应的ActorChannel执行.
- Server: ActorChannel对Bunch disassemble后查看RPC数据,并使用RPC ID和序列化参数调用Actor上的对应函数
Send Sequence
- 服务端调用标记为UFUNCTION(Client)的函数
- 通过UObject::ProcessEvent调用AActor::CallRemoteFunction.(AActor::CallRemoteFunction该函数在UObject中声明,但其实现仅仅return false,这也是为什么UObject不支持RPC的原因)
- 执行UNetDriver::ProcessRemoteFunction(如果Replication!=nulpttr 如果Replication::ProcessRemoteFunction)
- UNetDriver::InternalProcessremoteFunction中创建通信的Actor对应的UActorChannel(如果是第一次通信的话)
ProcessremoteFunctionForChannel中通过UActorChannel::ReplicateActor序列化后发送数据包。(对于!bReliable && Multicast,不需要加入队列直接发送UActorChannel::SendBunch,UActorChannel::QueueRemoteFunctionBunch)
RPC堆栈接收.pngRecv Sequence
- UIpNetDriver::TickDispatch
- UNetConnection::ReceivedRawPacket
- UNetConnection::ReceivedPacket
- UChannel::ReceivedRawBunch
- UChannel::ReceivedNextBunch
- UChannel::ReceivedSequencedBunch
- UActorChannel::ReceivedBunch
- UActorChannel::ProcessBunch
- FObjectReplicator::ReceivedBunch
- FObjectReplicator::ReceivedRPC
- AActor::ProcessEvent
UFunction::Invoke
RPC堆栈(创建HUD).png
断线重连
- IpNetDriver::ProcessConnectionlessPacket