Skip to content

Commit

Permalink
feat: Disposable PooledNetworkReader / PooledNetworkWriter (#1490)
Browse files Browse the repository at this point in the history
* Inherit IDisposable

* using NetworkWriter from pool

* Remove Recycles

* Add comments to Recycle

* Add comments to Recycle

* using NetworkReader from pool

* Unity doesn't like the simplified form

* combined usings

* Updated Reader / Writer Tests

* wip

* Disposable NetworkReaderPool:NetworkReader

* uncomment NetworkDiagnostics.OnReceive

* Removed unnecessary constructor

* Implemented NetworkWriterPool : NetworkWriter

* code cleanup

* Separated classes: PooledNetworkReader / PooledNetworkWriter

* Removed blank line

* Update Assets/Mirror/Tests/Editor/NetworkReaderTest.cs

* Test restored

Co-authored-by: Paul Pacheco <paulpach@gmail.com>
  • Loading branch information
MrGadget and paulpach committed Feb 10, 2020
1 parent 436d8fe commit bb55baa
Show file tree
Hide file tree
Showing 15 changed files with 398 additions and 375 deletions.
104 changes: 46 additions & 58 deletions Assets/Mirror/Components/Discovery/NetworkDiscoveryBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,22 +158,20 @@ async Task ReceiveRequestAsync(UdpClient udpClient)

UdpReceiveResult udpReceiveResult = await udpClient.ReceiveAsync();

NetworkReader networkReader = NetworkReaderPool.GetReader(udpReceiveResult.Buffer);

long handshake = networkReader.ReadInt64();
if (handshake != secretHandshake)
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(udpReceiveResult.Buffer))
{
// message is not for us
NetworkReaderPool.Recycle(networkReader);
throw new ProtocolViolationException("Invalid handshake");
}

Request request = new Request();
request.Deserialize(networkReader);
long handshake = networkReader.ReadInt64();
if (handshake != secretHandshake)
{
// message is not for us
throw new ProtocolViolationException("Invalid handshake");
}

ProcessClientRequest(request, udpReceiveResult.RemoteEndPoint);
Request request = new Request();
request.Deserialize(networkReader);

NetworkReaderPool.Recycle(networkReader);
ProcessClientRequest(request, udpReceiveResult.RemoteEndPoint);
}
}

/// <summary>
Expand All @@ -192,26 +190,23 @@ protected virtual void ProcessClientRequest(Request request, IPEndPoint endpoint
if (info == null)
return;

NetworkWriter writer = NetworkWriterPool.GetWriter();

try
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
{
writer.WriteInt64(secretHandshake);
try
{
writer.WriteInt64(secretHandshake);

info.Serialize(writer);
info.Serialize(writer);

ArraySegment<byte> data = writer.ToArraySegment();
// signature matches
// send response
serverUdpClient.Send(data.Array, data.Count, endpoint);
}
catch (Exception ex)
{
Debug.LogException(ex, this);
}
finally
{
NetworkWriterPool.Recycle(writer);
ArraySegment<byte> data = writer.ToArraySegment();
// signature matches
// send response
serverUdpClient.Send(data.Array, data.Count, endpoint);
}
catch (Exception ex)
{
Debug.LogException(ex, this);
}
}
}

Expand Down Expand Up @@ -304,27 +299,24 @@ public void BroadcastDiscoveryRequest()

IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, serverBroadcastListenPort);

NetworkWriter writer = NetworkWriterPool.GetWriter();

writer.WriteInt64(secretHandshake);

try
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
{
Request request = GetRequest();
writer.WriteInt64(secretHandshake);

request.Serialize(writer);
try
{
Request request = GetRequest();

ArraySegment<byte> data = writer.ToArraySegment();
request.Serialize(writer);

clientUdpClient.SendAsync(data.Array, data.Count, endPoint);
}
catch (Exception)
{
// It is ok if we can't broadcast to one of the addresses
}
finally
{
NetworkWriterPool.Recycle(writer);
ArraySegment<byte> data = writer.ToArraySegment();

clientUdpClient.SendAsync(data.Array, data.Count, endPoint);
}
catch (Exception)
{
// It is ok if we can't broadcast to one of the addresses
}
}
}

Expand All @@ -344,20 +336,16 @@ async Task ReceiveGameBroadcastAsync(UdpClient udpClient)

UdpReceiveResult udpReceiveResult = await udpClient.ReceiveAsync();

NetworkReader networkReader = NetworkReaderPool.GetReader(udpReceiveResult.Buffer);

if (networkReader.ReadInt64() != secretHandshake)
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(udpReceiveResult.Buffer))
{
NetworkReaderPool.Recycle(networkReader);
return;
}

Response response = new Response();
response.Deserialize(networkReader);
if (networkReader.ReadInt64() != secretHandshake)
return;

ProcessResponse(response, udpReceiveResult.RemoteEndPoint);
Response response = new Response();
response.Deserialize(networkReader);

NetworkReaderPool.Recycle(networkReader);
ProcessResponse(response, udpReceiveResult.RemoteEndPoint);
}
}

/// <summary>
Expand Down
47 changes: 22 additions & 25 deletions Assets/Mirror/Components/NetworkAnimator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ void FixedUpdate()
continue;
}

NetworkWriter writer = NetworkWriterPool.GetWriter();
WriteParameters(writer);

SendAnimationMessage(stateHash, normalizedTime, i, writer.ToArray());
NetworkWriterPool.Recycle(writer);
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
{
WriteParameters(writer);
SendAnimationMessage(stateHash, normalizedTime, i, writer.ToArray());
}
}
}

Expand Down Expand Up @@ -140,12 +140,11 @@ void CheckSendRate()
{
sendTimer = Time.time + syncInterval;

NetworkWriter writer = NetworkWriterPool.GetWriter();
if (WriteParameters(writer))
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
{
SendAnimationParametersMessage(writer.ToArray());
if (WriteParameters(writer))
SendAnimationParametersMessage(writer.ToArray());
}
NetworkWriterPool.Recycle(writer);
}
}

Expand Down Expand Up @@ -454,22 +453,22 @@ void CmdOnAnimationServerMessage(int stateHash, float normalizedTime, int layerI
if (LogFilter.Debug) Debug.Log("OnAnimationMessage for netId=" + netId);

// handle and broadcast
NetworkReader networkReader = NetworkReaderPool.GetReader(parameters);
HandleAnimMsg(stateHash, normalizedTime, layerId, networkReader);
NetworkReaderPool.Recycle(networkReader);

RpcOnAnimationClientMessage(stateHash, normalizedTime, layerId, parameters);
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(parameters))
{
HandleAnimMsg(stateHash, normalizedTime, layerId, networkReader);
RpcOnAnimationClientMessage(stateHash, normalizedTime, layerId, parameters);
}
}

[Command]
void CmdOnAnimationParametersServerMessage(byte[] parameters)
{
// handle and broadcast
NetworkReader networkReader = NetworkReaderPool.GetReader(parameters);
HandleAnimParamsMsg(networkReader);
NetworkReaderPool.Recycle(networkReader);

RpcOnAnimationParametersClientMessage(parameters);
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(parameters))
{
HandleAnimParamsMsg(networkReader);
RpcOnAnimationParametersClientMessage(parameters);
}
}

[Command]
Expand All @@ -495,17 +494,15 @@ void CmdOnAnimationResetTriggerServerMessage(int hash)
[ClientRpc]
void RpcOnAnimationClientMessage(int stateHash, float normalizedTime, int layerId, byte[] parameters)
{
NetworkReader networkReader = NetworkReaderPool.GetReader(parameters);
HandleAnimMsg(stateHash, normalizedTime, layerId, networkReader);
NetworkReaderPool.Recycle(networkReader);
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(parameters))
HandleAnimMsg(stateHash, normalizedTime, layerId, networkReader);
}

[ClientRpc]
void RpcOnAnimationParametersClientMessage(byte[] parameters)
{
NetworkReader networkReader = NetworkReaderPool.GetReader(parameters);
HandleAnimParamsMsg(networkReader);
NetworkReaderPool.Recycle(networkReader);
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(parameters))
HandleAnimParamsMsg(networkReader);
}

[ClientRpc]
Expand Down
16 changes: 8 additions & 8 deletions Assets/Mirror/Components/NetworkTransformBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,8 @@ public override void OnDeserialize(NetworkReader reader, bool initialState)
void CmdClientToServerSync(byte[] payload)
{
// deserialize payload
NetworkReader networkReader = NetworkReaderPool.GetReader(payload);
DeserializeFromReader(networkReader);
NetworkReaderPool.Recycle(networkReader);
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(payload))
DeserializeFromReader(networkReader);

// server-only mode does no interpolation to save computations,
// but let's set the position directly
Expand Down Expand Up @@ -395,12 +394,13 @@ void Update()
{
// serialize
// local position/rotation for VR support
NetworkWriter writer = NetworkWriterPool.GetWriter();
SerializeIntoWriter(writer, targetComponent.transform.localPosition, targetComponent.transform.localRotation, compressRotation, targetComponent.transform.localScale);
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
{
SerializeIntoWriter(writer, targetComponent.transform.localPosition, targetComponent.transform.localRotation, compressRotation, targetComponent.transform.localScale);

// send to server
CmdClientToServerSync(writer.ToArray());
NetworkWriterPool.Recycle(writer);
// send to server
CmdClientToServerSync(writer.ToArray());
}
}
lastClientSendTime = Time.time;
}
Expand Down
8 changes: 4 additions & 4 deletions Assets/Mirror/Examples/AdditiveScenes/Scenes/MainScene.unity
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 160176459, guid: ab222ed73ada1ac4ba2f61e843d7627c, type: 3}
propertyPath: sceneId
value: 2634699359
value: 1521238664
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: ab222ed73ada1ac4ba2f61e843d7627c, type: 3}
Expand Down Expand Up @@ -925,7 +925,7 @@ PrefabInstance:
- target: {fileID: 855244094988030911, guid: f6d08eb9a8e35d84fa30a7e3ae64181a,
type: 3}
propertyPath: sceneId
value: 609992951
value: 744240842
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: f6d08eb9a8e35d84fa30a7e3ae64181a, type: 3}
Expand Down Expand Up @@ -1198,7 +1198,7 @@ PrefabInstance:
- target: {fileID: 6852530814182375318, guid: 12a4c14e672c00b4b840f937d824b890,
type: 3}
propertyPath: sceneId
value: 3536086708
value: 1418438611
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 12a4c14e672c00b4b840f937d824b890, type: 3}
Expand Down Expand Up @@ -2114,7 +2114,7 @@ PrefabInstance:
- target: {fileID: 2648107611936813301, guid: e1971f4a8c7661546bc509b44bd91b80,
type: 3}
propertyPath: sceneId
value: 475777495
value: 2757245015
objectReference: {fileID: 0}
- target: {fileID: 5697694911122891659, guid: e1971f4a8c7661546bc509b44bd91b80,
type: 3}
Expand Down
22 changes: 10 additions & 12 deletions Assets/Mirror/Runtime/ClientScene.cs
Original file line number Diff line number Diff line change
Expand Up @@ -494,9 +494,10 @@ static void ApplySpawnPayload(NetworkIdentity identity, SpawnMessage msg)
// (Count is 0 if there were no components)
if (msg.payload.Count > 0)
{
NetworkReader payloadReader = NetworkReaderPool.GetReader(msg.payload);
identity.OnUpdateVars(payloadReader, true);
NetworkReaderPool.Recycle(payloadReader);
using (PooledNetworkReader payloadReader = NetworkReaderPool.GetReader(msg.payload))
{
identity.OnUpdateVars(payloadReader, true);
}
}

NetworkIdentity.spawned[msg.netId] = identity;
Expand Down Expand Up @@ -690,9 +691,8 @@ internal static void OnUpdateVarsMessage(UpdateVarsMessage msg)

if (NetworkIdentity.spawned.TryGetValue(msg.netId, out NetworkIdentity localObject) && localObject != null)
{
NetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload);
localObject.OnUpdateVars(networkReader, false);
NetworkReaderPool.Recycle(networkReader);
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload))
localObject.OnUpdateVars(networkReader, false);
}
else
{
Expand All @@ -706,9 +706,8 @@ internal static void OnRPCMessage(RpcMessage msg)

if (NetworkIdentity.spawned.TryGetValue(msg.netId, out NetworkIdentity identity))
{
NetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload);
identity.HandleRPC(msg.componentIndex, msg.functionHash, networkReader);
NetworkReaderPool.Recycle(networkReader);
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload))
identity.HandleRPC(msg.componentIndex, msg.functionHash, networkReader);
}
}

Expand All @@ -718,9 +717,8 @@ internal static void OnSyncEventMessage(SyncEventMessage msg)

if (NetworkIdentity.spawned.TryGetValue(msg.netId, out NetworkIdentity identity))
{
NetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload);
identity.HandleSyncEvent(msg.componentIndex, msg.functionHash, networkReader);
NetworkReaderPool.Recycle(networkReader);
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload))
identity.HandleSyncEvent(msg.componentIndex, msg.functionHash, networkReader);
}
else
{
Expand Down

0 comments on commit bb55baa

Please sign in to comment.