-
Notifications
You must be signed in to change notification settings - Fork 461
Fix: Loopback RPCs in host mode #460
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3018a64
5b047ff
f0e4a46
e1f2d8f
7142ed2
a3fc0b4
0245c92
df6693a
c6642bb
4c13503
5765b7b
f6a0959
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -67,24 +67,40 @@ public BitSerializer __beginSendServerRpc(ServerRpcParams serverRpcParams, bool | |
| #endif | ||
| { | ||
| var rpcQueueContainer = NetworkingManager.Singleton.rpcQueueContainer; | ||
| var writer = rpcQueueContainer.BeginAddQueueItemToOutboundFrame( | ||
| RpcQueueContainer.QueueItemType.ServerRpc, | ||
| Time.realtimeSinceStartup, | ||
| Transport.MLAPI_STDRPC_CHANNEL, | ||
| /* sendFlags = */ 0, | ||
| NetworkingManager.Singleton.ServerClientId, | ||
| /* targetNetworkIds = */ null); | ||
| if (!rpcQueueContainer.IsUsingBatching()) | ||
| PooledBitWriter writer; | ||
| var IsUsingBatching = rpcQueueContainer.IsUsingBatching(); | ||
| if (IsHost) | ||
| { | ||
| if (serverRpcParams.Send.UpdateStage == NetworkUpdateManager.NetworkUpdateStage.Default) | ||
| { | ||
| serverRpcParams.Send.UpdateStage = NetworkUpdateManager.NetworkUpdateStage.Update; | ||
| } | ||
| writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ServerRpc, Time.realtimeSinceStartup, Transport.MLAPI_STDRPC_CHANNEL, 0, | ||
| NetworkingManager.Singleton.ServerClientId, null, QueueHistoryFrame.QueueFrameType.Inbound,serverRpcParams.Send.UpdateStage ); | ||
|
|
||
| //Under this condition we always treat this like there is no batching | ||
| writer.WriteBit(false); // Encrypted | ||
| writer.WriteBit(false); // Authenticated | ||
| writer.WriteBits(MLAPIConstants.MLAPI_SERVER_RPC, 6); // MessageType | ||
| } | ||
| else | ||
| { | ||
| writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ServerRpc, Time.realtimeSinceStartup, Transport.MLAPI_STDRPC_CHANNEL, 0, | ||
| NetworkingManager.Singleton.ServerClientId, null, QueueHistoryFrame.QueueFrameType.Outbound, NetworkUpdateManager.NetworkUpdateStage.LateUpdate); | ||
| if (!IsUsingBatching) | ||
| { | ||
| writer.WriteBit(false); // Encrypted | ||
| writer.WriteBit(false); // Authenticated | ||
| writer.WriteBits(MLAPIConstants.MLAPI_SERVER_RPC, 6); // MessageType | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
|
||
| writer.WriteUInt64Packed(NetworkId); // NetworkObjectId | ||
| writer.WriteUInt16Packed(GetBehaviourId()); // NetworkBehaviourId | ||
|
|
||
| // Write the update stage in front of RPC related information | ||
| //Write the update stage in front of RPC related information | ||
| if (serverRpcParams.Send.UpdateStage == NetworkUpdateManager.NetworkUpdateStage.Default) | ||
| { | ||
| writer.WriteUInt16Packed((ushort)NetworkUpdateManager.NetworkUpdateStage.Update); | ||
|
|
@@ -110,7 +126,15 @@ public void __endSendServerRpc(BitSerializer serializer, ServerRpcParams serverR | |
| if (serializer == null) return; | ||
|
|
||
| var rpcQueueContainer = NetworkingManager.Singleton.rpcQueueContainer; | ||
| rpcQueueContainer.EndAddQueueItemToOutboundFrame(serializer.Writer); | ||
| if (IsHost) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, see my comment on host mode above |
||
| { | ||
| rpcQueueContainer.EndAddQueueItemToFrame(serializer.Writer, QueueHistoryFrame.QueueFrameType.Inbound, serverRpcParams.Send.UpdateStage == NetworkUpdateManager.NetworkUpdateStage.Default ? NetworkUpdateManager.NetworkUpdateStage.Update:serverRpcParams.Send.UpdateStage ); | ||
| } | ||
| else | ||
| { | ||
| rpcQueueContainer.EndAddQueueItemToFrame(serializer.Writer, QueueHistoryFrame.QueueFrameType.Outbound, NetworkUpdateManager.NetworkUpdateStage.LateUpdate); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| [Browsable(false)] | ||
|
|
@@ -125,18 +149,57 @@ public BitSerializer __beginSendClientRpc(ClientRpcParams clientRpcParams, bool | |
| { | ||
| // This will start a new queue item entry and will then return the writer to the current frame's stream | ||
| var rpcQueueContainer = NetworkingManager.Singleton.rpcQueueContainer; | ||
| var writer = rpcQueueContainer.BeginAddQueueItemToOutboundFrame( | ||
| RpcQueueContainer.QueueItemType.ClientRpc, | ||
| Time.realtimeSinceStartup, | ||
| Transport.MLAPI_STDRPC_CHANNEL, | ||
| /* sendFlags = */ 0, | ||
| NetworkId, | ||
| clientRpcParams.Send.TargetClientIds ?? NetworkingManager.Singleton.ConnectedClientsList.Select(c => c.ClientId).ToArray()); | ||
| if (!rpcQueueContainer.IsUsingBatching()) | ||
|
|
||
| PooledBitWriter writer; | ||
| var IsUsingBatching = rpcQueueContainer.IsUsingBatching(); | ||
|
|
||
| ulong[] ClientIds = clientRpcParams.Send.TargetClientIds ?? NetworkingManager.Singleton.ConnectedClientsList.Select(c => c.ClientId).ToArray(); | ||
| if(clientRpcParams.Send.TargetClientIds != null && clientRpcParams.Send.TargetClientIds.Length == 0) | ||
| { | ||
| ClientIds = NetworkingManager.Singleton.ConnectedClientsList.Select(c => c.ClientId).ToArray(); | ||
| } | ||
|
|
||
| var ContainsServerClientId = ClientIds.Contains(NetworkingManager.Singleton.ServerClientId); | ||
| if (IsHost && ContainsServerClientId) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto ditto on host mode |
||
| { | ||
| if(clientRpcParams.Send.UpdateStage == NetworkUpdateManager.NetworkUpdateStage.Default) | ||
| { | ||
| clientRpcParams.Send.UpdateStage = NetworkUpdateManager.NetworkUpdateStage.Update; | ||
| } | ||
|
|
||
| writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ClientRpc, Time.realtimeSinceStartup, Transport.MLAPI_STDRPC_CHANNEL, 0, | ||
| NetworkingManager.Singleton.ServerClientId, null, QueueHistoryFrame.QueueFrameType.Inbound,clientRpcParams.Send.UpdateStage ); | ||
|
|
||
| writer.WriteBit(false); // Encrypted | ||
| writer.WriteBit(false); // Authenticated | ||
| writer.WriteBits(MLAPIConstants.MLAPI_CLIENT_RPC, 6); // MessageType | ||
|
|
||
| //Handle sending to the other clients | ||
| if (ClientIds.Length > 1 ) | ||
| { | ||
| rpcQueueContainer.SetLoopBackWriter(writer, QueueHistoryFrame.QueueFrameType.Outbound, NetworkUpdateManager.NetworkUpdateStage.LateUpdate); | ||
| writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ClientRpc, Time.realtimeSinceStartup, Transport.MLAPI_STDRPC_CHANNEL, 0, NetworkId, | ||
| ClientIds, QueueHistoryFrame.QueueFrameType.Outbound, NetworkUpdateManager.NetworkUpdateStage.LateUpdate); | ||
|
|
||
| if (!IsUsingBatching) | ||
| { | ||
| writer.WriteBit(false); // Encrypted | ||
| writer.WriteBit(false); // Authenticated | ||
| writer.WriteBits(MLAPIConstants.MLAPI_CLIENT_RPC, 6); // MessageType | ||
| } | ||
| } | ||
| } | ||
| else | ||
| { | ||
| writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ClientRpc, Time.realtimeSinceStartup, Transport.MLAPI_STDRPC_CHANNEL, 0, NetworkId, | ||
| ClientIds, QueueHistoryFrame.QueueFrameType.Outbound, NetworkUpdateManager.NetworkUpdateStage.LateUpdate); | ||
|
|
||
| if (!IsUsingBatching) | ||
| { | ||
| writer.WriteBit(false); // Encrypted | ||
| writer.WriteBit(false); // Authenticated | ||
| writer.WriteBits(MLAPIConstants.MLAPI_CLIENT_RPC, 6); // MessageType | ||
| } | ||
| } | ||
|
|
||
| writer.WriteUInt64Packed(NetworkId); // NetworkObjectId | ||
|
|
@@ -155,6 +218,7 @@ public BitSerializer __beginSendClientRpc(ClientRpcParams clientRpcParams, bool | |
| return writer.Serializer; | ||
| } | ||
|
|
||
|
|
||
| [Browsable(false)] | ||
| [EditorBrowsable(EditorBrowsableState.Never)] | ||
| #if UNITY_2020_2_OR_NEWER | ||
|
|
@@ -168,7 +232,33 @@ public void __endSendClientRpc(BitSerializer serializer, ClientRpcParams clientR | |
| if (serializer == null) return; | ||
|
|
||
| var rpcQueueContainer = NetworkingManager.Singleton.rpcQueueContainer; | ||
| rpcQueueContainer.EndAddQueueItemToOutboundFrame(serializer.Writer); | ||
| ulong[] ClientIds = clientRpcParams.Send.TargetClientIds ?? NetworkingManager.Singleton.ConnectedClientsList.Select(c => c.ClientId).ToArray(); | ||
| if(clientRpcParams.Send.TargetClientIds != null && clientRpcParams.Send.TargetClientIds.Length == 0) | ||
| { | ||
| ClientIds = NetworkingManager.Singleton.ConnectedClientsList.Select(c => c.ClientId).ToArray(); | ||
| } | ||
| var ContainsServerClientId = ClientIds.Contains(NetworkingManager.Singleton.ServerClientId); | ||
|
|
||
| if (IsHost && ContainsServerClientId) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto ditto ditto on host mode :) |
||
| { | ||
| PooledBitWriter loopbackWriter = serializer.Writer as PooledBitWriter; | ||
| if (ClientIds.Length > 1 ) | ||
| { | ||
| rpcQueueContainer.EndAddQueueItemToFrame(serializer.Writer, QueueHistoryFrame.QueueFrameType.Outbound, NetworkUpdateManager.NetworkUpdateStage.LateUpdate); | ||
|
|
||
| loopbackWriter = rpcQueueContainer.GetLoopBackWriter(QueueHistoryFrame.QueueFrameType.Outbound, NetworkUpdateManager.NetworkUpdateStage.LateUpdate); | ||
| rpcQueueContainer.ClearLoopBackWriter(QueueHistoryFrame.QueueFrameType.Outbound, NetworkUpdateManager.NetworkUpdateStage.LateUpdate); | ||
| } | ||
|
|
||
| if(ContainsServerClientId) | ||
| { | ||
| rpcQueueContainer.EndAddQueueItemToFrame(loopbackWriter, QueueHistoryFrame.QueueFrameType.Inbound, clientRpcParams.Send.UpdateStage == NetworkUpdateManager.NetworkUpdateStage.Default ? NetworkUpdateManager.NetworkUpdateStage.Update:clientRpcParams.Send.UpdateStage ); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| rpcQueueContainer.EndAddQueueItemToFrame(serializer.Writer, QueueHistoryFrame.QueueFrameType.Outbound, NetworkUpdateManager.NetworkUpdateStage.LateUpdate); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this because technically we don't need to batch when in host (vs. server) mode? Or because batching doesn't work in host mode? My thinking is, I really would like to avoid the host mode special case code in general because I think we tend to test one or the other leading to latent bugs. If we don't need to special case host mode then could we meld the if and else clauses into one?