mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 11:00:32 +00:00
feat: Implemented NetworkReaderPool (#1464)
* Implement NetworkReaderPool * Reset Position * Debug logging removed * SetBuffer methods internal * Edited comment
This commit is contained in:
parent
abb570b309
commit
9257112c65
@ -147,19 +147,22 @@ async Task ReceiveRequestAsync(UdpClient udpClient)
|
||||
|
||||
UdpReceiveResult udpReceiveResult = await udpClient.ReceiveAsync();
|
||||
|
||||
NetworkReader reader = new NetworkReader(udpReceiveResult.Buffer);
|
||||
NetworkReader networkReader = NetworkReaderPool.GetReader(udpReceiveResult.Buffer);
|
||||
|
||||
long handshake = reader.ReadInt64();
|
||||
long handshake = networkReader.ReadInt64();
|
||||
if (handshake != secretHandshake)
|
||||
{
|
||||
// message is not for us
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
throw new ProtocolViolationException("Invalid handshake");
|
||||
}
|
||||
|
||||
Request request = new Request();
|
||||
request.Deserialize(reader);
|
||||
request.Deserialize(networkReader);
|
||||
|
||||
ProcessClientRequest(request, udpReceiveResult.RemoteEndPoint);
|
||||
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -330,15 +333,20 @@ async Task ReceiveGameBroadcastAsync(UdpClient udpClient)
|
||||
|
||||
UdpReceiveResult udpReceiveResult = await udpClient.ReceiveAsync();
|
||||
|
||||
NetworkReader reader = new NetworkReader(udpReceiveResult.Buffer);
|
||||
NetworkReader networkReader = NetworkReaderPool.GetReader(udpReceiveResult.Buffer);
|
||||
|
||||
if (reader.ReadInt64() != secretHandshake)
|
||||
if (networkReader.ReadInt64() != secretHandshake)
|
||||
{
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
return;
|
||||
}
|
||||
|
||||
Response response = new Response();
|
||||
response.Deserialize(reader);
|
||||
response.Deserialize(networkReader);
|
||||
|
||||
ProcessResponse(response, udpReceiveResult.RemoteEndPoint);
|
||||
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -451,7 +451,10 @@ void CmdOnAnimationServerMessage(int stateHash, float normalizedTime, int layerI
|
||||
if (LogFilter.Debug) Debug.Log("OnAnimationMessage for netId=" + netId);
|
||||
|
||||
// handle and broadcast
|
||||
HandleAnimMsg(stateHash, normalizedTime, layerId, new NetworkReader(parameters));
|
||||
NetworkReader networkReader = NetworkReaderPool.GetReader(parameters);
|
||||
HandleAnimMsg(stateHash, normalizedTime, layerId, networkReader);
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
|
||||
RpcOnAnimationClientMessage(stateHash, normalizedTime, layerId, parameters);
|
||||
}
|
||||
|
||||
@ -459,7 +462,10 @@ void CmdOnAnimationServerMessage(int stateHash, float normalizedTime, int layerI
|
||||
void CmdOnAnimationParametersServerMessage(byte[] parameters)
|
||||
{
|
||||
// handle and broadcast
|
||||
HandleAnimParamsMsg(new NetworkReader(parameters));
|
||||
NetworkReader networkReader = NetworkReaderPool.GetReader(parameters);
|
||||
HandleAnimParamsMsg(networkReader);
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
|
||||
RpcOnAnimationParametersClientMessage(parameters);
|
||||
}
|
||||
|
||||
@ -486,13 +492,17 @@ void CmdOnAnimationResetTriggerServerMessage(int hash)
|
||||
[ClientRpc]
|
||||
void RpcOnAnimationClientMessage(int stateHash, float normalizedTime, int layerId, byte[] parameters)
|
||||
{
|
||||
HandleAnimMsg(stateHash, normalizedTime, layerId, new NetworkReader(parameters));
|
||||
NetworkReader networkReader = NetworkReaderPool.GetReader(parameters);
|
||||
HandleAnimMsg(stateHash, normalizedTime, layerId, networkReader);
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
}
|
||||
|
||||
[ClientRpc]
|
||||
void RpcOnAnimationParametersClientMessage(byte[] parameters)
|
||||
{
|
||||
HandleAnimParamsMsg(new NetworkReader(parameters));
|
||||
NetworkReader networkReader = NetworkReaderPool.GetReader(parameters);
|
||||
HandleAnimParamsMsg(networkReader);
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
}
|
||||
|
||||
[ClientRpc]
|
||||
|
@ -252,8 +252,9 @@ public override void OnDeserialize(NetworkReader reader, bool initialState)
|
||||
void CmdClientToServerSync(byte[] payload)
|
||||
{
|
||||
// deserialize payload
|
||||
NetworkReader reader = new NetworkReader(payload);
|
||||
DeserializeFromReader(reader);
|
||||
NetworkReader networkReader = NetworkReaderPool.GetReader(payload);
|
||||
DeserializeFromReader(networkReader);
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
|
||||
// server-only mode does no interpolation to save computations,
|
||||
// but let's set the position directly
|
||||
|
@ -488,8 +488,9 @@ static void ApplySpawnPayload(NetworkIdentity identity, SpawnMessage msg)
|
||||
// (Count is 0 if there were no components)
|
||||
if (msg.payload.Count > 0)
|
||||
{
|
||||
NetworkReader payloadReader = new NetworkReader(msg.payload);
|
||||
NetworkReader payloadReader = NetworkReaderPool.GetReader(msg.payload);
|
||||
identity.OnUpdateVars(payloadReader, true);
|
||||
NetworkReaderPool.Recycle(payloadReader);
|
||||
}
|
||||
|
||||
NetworkIdentity.spawned[msg.netId] = identity;
|
||||
@ -683,7 +684,9 @@ internal static void OnUpdateVarsMessage(UpdateVarsMessage msg)
|
||||
|
||||
if (NetworkIdentity.spawned.TryGetValue(msg.netId, out NetworkIdentity localObject) && localObject != null)
|
||||
{
|
||||
localObject.OnUpdateVars(new NetworkReader(msg.payload), false);
|
||||
NetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload);
|
||||
localObject.OnUpdateVars(networkReader, false);
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -697,7 +700,9 @@ internal static void OnRPCMessage(RpcMessage msg)
|
||||
|
||||
if (NetworkIdentity.spawned.TryGetValue(msg.netId, out NetworkIdentity identity))
|
||||
{
|
||||
identity.HandleRPC(msg.componentIndex, msg.functionHash, new NetworkReader(msg.payload));
|
||||
NetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload);
|
||||
identity.HandleRPC(msg.componentIndex, msg.functionHash, networkReader);
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
}
|
||||
}
|
||||
|
||||
@ -707,7 +712,9 @@ internal static void OnSyncEventMessage(SyncEventMessage msg)
|
||||
|
||||
if (NetworkIdentity.spawned.TryGetValue(msg.netId, out NetworkIdentity identity))
|
||||
{
|
||||
identity.HandleSyncEvent(msg.componentIndex, msg.functionHash, new NetworkReader(msg.payload));
|
||||
NetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload);
|
||||
identity.HandleSyncEvent(msg.componentIndex, msg.functionHash, networkReader);
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -89,16 +89,22 @@ public static byte[] Pack<T>(T message) where T : IMessageBase
|
||||
// unpack a message we received
|
||||
public static T Unpack<T>(byte[] data) where T : IMessageBase, new()
|
||||
{
|
||||
NetworkReader reader = new NetworkReader(data);
|
||||
NetworkReader networkReader = NetworkReaderPool.GetReader(data);
|
||||
|
||||
int msgType = GetId<T>();
|
||||
|
||||
int id = reader.ReadUInt16();
|
||||
int id = networkReader.ReadUInt16();
|
||||
if (id != msgType)
|
||||
{
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
throw new FormatException("Invalid message, could not unpack " + typeof(T).FullName);
|
||||
}
|
||||
|
||||
T message = new T();
|
||||
message.Deserialize(reader);
|
||||
message.Deserialize(networkReader);
|
||||
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
@ -325,7 +325,9 @@ public bool InvokeHandler<T>(T msg, int channelId) where T : IMessageBase
|
||||
|
||||
MessagePacker.Pack(msg, writer);
|
||||
ArraySegment<byte> segment = writer.ToArraySegment();
|
||||
bool result = InvokeHandler(msgType, new NetworkReader(segment), channelId);
|
||||
NetworkReader networkReader = NetworkReaderPool.GetReader(segment);
|
||||
bool result = InvokeHandler(msgType, networkReader, channelId);
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
|
||||
// recycle writer and return
|
||||
NetworkWriterPool.Recycle(writer);
|
||||
@ -345,14 +347,14 @@ public bool InvokeHandler<T>(T msg, int channelId) where T : IMessageBase
|
||||
internal void TransportReceive(ArraySegment<byte> buffer, int channelId)
|
||||
{
|
||||
// unpack message
|
||||
NetworkReader reader = new NetworkReader(buffer);
|
||||
if (MessagePacker.UnpackMessage(reader, out int msgType))
|
||||
NetworkReader networkReader = NetworkReaderPool.GetReader(buffer);
|
||||
if (MessagePacker.UnpackMessage(networkReader, out int msgType))
|
||||
{
|
||||
// logging
|
||||
if (logNetworkMessages) Debug.Log("ConnectionRecv " + this + " msgType:" + msgType + " content:" + BitConverter.ToString(buffer.Array, buffer.Offset, buffer.Count));
|
||||
|
||||
// try to invoke the handler for that message
|
||||
if (InvokeHandler(msgType, reader, channelId))
|
||||
if (InvokeHandler(msgType, networkReader, channelId))
|
||||
{
|
||||
lastMessageTime = Time.time;
|
||||
}
|
||||
@ -362,6 +364,8 @@ internal void TransportReceive(ArraySegment<byte> buffer, int channelId)
|
||||
Debug.LogError("Closed connection: " + this + ". Invalid message header.");
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
}
|
||||
|
||||
internal void AddOwnedObject(NetworkIdentity obj)
|
||||
|
@ -28,7 +28,6 @@ public class NetworkReader
|
||||
public int Position;
|
||||
public int Length => buffer.Count;
|
||||
|
||||
|
||||
public NetworkReader(byte[] bytes)
|
||||
{
|
||||
buffer = new ArraySegment<byte>(bytes);
|
||||
@ -39,6 +38,20 @@ public NetworkReader(ArraySegment<byte> segment)
|
||||
buffer = segment;
|
||||
}
|
||||
|
||||
// SetBuffer methods mirror constructor for ReaderPool
|
||||
internal void SetBuffer(byte[] bytes)
|
||||
{
|
||||
buffer = new ArraySegment<byte>(bytes);
|
||||
Position = 0;
|
||||
}
|
||||
|
||||
internal void SetBuffer(ArraySegment<byte> segment)
|
||||
{
|
||||
buffer = segment;
|
||||
Position = 0;
|
||||
}
|
||||
|
||||
|
||||
public byte ReadByte()
|
||||
{
|
||||
if (Position + 1 > buffer.Count)
|
||||
|
41
Assets/Mirror/Runtime/NetworkReaderPool.cs
Normal file
41
Assets/Mirror/Runtime/NetworkReaderPool.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Mirror
|
||||
{
|
||||
public static class NetworkReaderPool
|
||||
{
|
||||
static readonly Stack<NetworkReader> pool = new Stack<NetworkReader>();
|
||||
|
||||
public static NetworkReader GetReader(byte[] bytes)
|
||||
{
|
||||
if (pool.Count != 0)
|
||||
{
|
||||
NetworkReader reader = pool.Pop();
|
||||
// reset buffer
|
||||
reader.SetBuffer(bytes);
|
||||
return reader;
|
||||
}
|
||||
|
||||
return new NetworkReader(bytes);
|
||||
}
|
||||
|
||||
public static NetworkReader GetReader(ArraySegment<byte> segment)
|
||||
{
|
||||
if (pool.Count != 0)
|
||||
{
|
||||
NetworkReader reader = pool.Pop();
|
||||
// reset buffer
|
||||
reader.SetBuffer(segment);
|
||||
return reader;
|
||||
}
|
||||
|
||||
return new NetworkReader(segment);
|
||||
}
|
||||
|
||||
public static void Recycle(NetworkReader reader)
|
||||
{
|
||||
pool.Push(reader);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Mirror/Runtime/NetworkReaderPool.cs.meta
Normal file
11
Assets/Mirror/Runtime/NetworkReaderPool.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bacff63613ad634a98f9e4d15d29dbf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1016,7 +1016,10 @@ static void OnCommandMessage(NetworkConnection conn, CommandMessage msg)
|
||||
}
|
||||
|
||||
if (LogFilter.Debug) Debug.Log("OnCommandMessage for netId=" + msg.netId + " conn=" + conn);
|
||||
identity.HandleCommand(msg.componentIndex, msg.functionHash, new NetworkReader(msg.payload));
|
||||
|
||||
NetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload);
|
||||
identity.HandleCommand(msg.componentIndex, msg.functionHash, networkReader);
|
||||
NetworkReaderPool.Recycle(networkReader);
|
||||
}
|
||||
|
||||
internal static void SpawnObject(GameObject obj, NetworkConnection ownerConnection)
|
||||
|
Loading…
Reference in New Issue
Block a user