Skip to content

Commit

Permalink
perf: Transports now give ArraySegment<byte> instead of byte[] (based…
Browse files Browse the repository at this point in the history
… on #569 and #846)

perf: Transports now give ArraySegment<byte> instead of byte[] (based on #569 and #846)
  • Loading branch information
miwarnec committed Apr 28, 2019
1 parent 6c4b34b commit 77bee45
Show file tree
Hide file tree
Showing 11 changed files with 34 additions and 30 deletions.
3 changes: 2 additions & 1 deletion Assets/Mirror/Runtime/LocalConnections.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using UnityEngine;

namespace Mirror
Expand Down Expand Up @@ -39,7 +40,7 @@ internal override bool SendBytes(byte[] bytes, int channelId = Channels.DefaultR

// handle the server's message directly
// TODO any way to do this without NetworkServer.localConnection?
NetworkServer.localConnection.TransportReceive(bytes);
NetworkServer.localConnection.TransportReceive(new ArraySegment<byte>(bytes));
return true;
}
}
Expand Down
4 changes: 2 additions & 2 deletions Assets/Mirror/Runtime/NetworkClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ static void OnDisconnected()
connection?.InvokeHandler(new DisconnectMessage());
}

internal static void OnDataReceived(byte[] data)
internal static void OnDataReceived(ArraySegment<byte> data)
{
if (connection != null)
{
Expand Down Expand Up @@ -219,7 +219,7 @@ internal static void Update()
while (localClientPacketQueue.Count > 0)
{
byte[] packet = localClientPacketQueue.Dequeue();
OnDataReceived(packet);
OnDataReceived(new ArraySegment<byte>(packet));
}
}
else
Expand Down
4 changes: 2 additions & 2 deletions Assets/Mirror/Runtime/NetworkConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,14 +223,14 @@ internal bool InvokeHandler(int msgType, NetworkReader reader)
// -> in other words, we always receive 1 message per Receive call, never two.
// -> can be tested easily with a 1000ms send delay and then logging amount received in while loops here
// and in NetworkServer/Client Update. HandleBytes already takes exactly one.
public virtual void TransportReceive(byte[] buffer)
public virtual void TransportReceive(ArraySegment<byte> buffer)
{
// unpack message
NetworkReader reader = new NetworkReader(buffer);
if (MessagePacker.UnpackMessage(reader, out int msgType))
{
// logging
if (logNetworkMessages) Debug.Log("ConnectionRecv con:" + connectionId + " msgType:" + msgType + " content:" + BitConverter.ToString(buffer));
if (logNetworkMessages) Debug.Log("ConnectionRecv con:" + connectionId + " msgType:" + msgType + " content:" + BitConverter.ToString(buffer.Array, buffer.Offset, buffer.Count));

// try to invoke the handler for that message
if (InvokeHandler(msgType, reader))
Expand Down
5 changes: 5 additions & 0 deletions Assets/Mirror/Runtime/NetworkReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public NetworkReader(byte[] buffer)
reader = new BinaryReader(new MemoryStream(buffer, false), encoding);
}

public NetworkReader(ArraySegment<byte> buffer)
{
reader = new BinaryReader(new MemoryStream(buffer.Array, buffer.Offset, buffer.Count, false), encoding);
}

// 'int' is the best type for .Position. 'short' is too small if we send >32kb which would result in negative .Position
// -> converting long to int is fine until 2GB of data (MAX_INT), so we don't have to worry about overflows here
public int Position { get { return (int)reader.BaseStream.Position; } set { reader.BaseStream.Position = value; } }
Expand Down
2 changes: 1 addition & 1 deletion Assets/Mirror/Runtime/NetworkServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ static void OnDisconnected(NetworkConnection conn)
if (LogFilter.Debug) Debug.Log("Server lost client:" + conn.connectionId);
}

static void OnDataReceived(int connectionId, byte[] data)
static void OnDataReceived(int connectionId, ArraySegment<byte> data)
{
if (connections.TryGetValue(connectionId, out NetworkConnection conn))
{
Expand Down
6 changes: 2 additions & 4 deletions Assets/Mirror/Runtime/Transport/LLAPITransport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ public bool ProcessClientMessage()
OnClientConnected.Invoke();
break;
case NetworkEventType.DataEvent:
byte[] data = new byte[receivedSize];
Array.Copy(clientReceiveBuffer, data, receivedSize);
ArraySegment<byte> data = new ArraySegment<byte>(clientReceiveBuffer, 0, receivedSize);
OnClientDataReceived.Invoke(data);
break;
case NetworkEventType.DisconnectEvent:
Expand Down Expand Up @@ -240,8 +239,7 @@ public bool ProcessServerMessage()
OnServerConnected.Invoke(connectionId);
break;
case NetworkEventType.DataEvent:
byte[] data = new byte[receivedSize];
Array.Copy(serverReceiveBuffer, data, receivedSize);
ArraySegment<byte> data = new ArraySegment<byte>(serverReceiveBuffer, 0, receivedSize);
OnServerDataReceived.Invoke(connectionId, data);
break;
case NetworkEventType.DisconnectEvent:
Expand Down
4 changes: 2 additions & 2 deletions Assets/Mirror/Runtime/Transport/TelepathyTransport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ bool ProcessClientMessage()
OnClientConnected.Invoke();
break;
case Telepathy.EventType.Data:
OnClientDataReceived.Invoke(message.data);
OnClientDataReceived.Invoke(new ArraySegment<byte>(message.data));
break;
case Telepathy.EventType.Disconnected:
OnClientDisconnected.Invoke();
Expand Down Expand Up @@ -111,7 +111,7 @@ public bool ProcessServerMessage()
OnServerConnected.Invoke(message.connectionId);
break;
case Telepathy.EventType.Data:
OnServerDataReceived.Invoke(message.connectionId, message.data);
OnServerDataReceived.Invoke(message.connectionId, new ArraySegment<byte>(message.data));
break;
case Telepathy.EventType.Disconnected:
OnServerDisconnected.Invoke(message.connectionId);
Expand Down
8 changes: 4 additions & 4 deletions Assets/Mirror/Runtime/Transport/Transport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
namespace Mirror
{
// UnityEvent definitions
[Serializable] public class UnityEventByteArray : UnityEvent<byte[]> {}
[Serializable] public class UnityEventArraySegment : UnityEvent<ArraySegment<byte>> {}
[Serializable] public class UnityEventException : UnityEvent<Exception> {}
[Serializable] public class UnityEventInt : UnityEvent<int> {}
[Serializable] public class UnityEventIntByteArray : UnityEvent<int, byte[]> {}
[Serializable] public class UnityEventIntArraySegment : UnityEvent<int, ArraySegment<byte>> {}
[Serializable] public class UnityEventIntException : UnityEvent<int, Exception> {}

public abstract class Transport : MonoBehaviour
Expand All @@ -29,7 +29,7 @@ public virtual bool Available()

// client
[HideInInspector] public UnityEvent OnClientConnected;
[HideInInspector] public UnityEventByteArray OnClientDataReceived;
[HideInInspector] public UnityEventArraySegment OnClientDataReceived;
[HideInInspector] public UnityEventException OnClientError;
[HideInInspector] public UnityEvent OnClientDisconnected;

Expand All @@ -40,7 +40,7 @@ public virtual bool Available()

// server
[HideInInspector] public UnityEventInt OnServerConnected;
[HideInInspector] public UnityEventIntByteArray OnServerDataReceived;
[HideInInspector] public UnityEventIntArraySegment OnServerDataReceived;
[HideInInspector] public UnityEventIntException OnServerError;
[HideInInspector] public UnityEventInt OnServerDisconnected;

Expand Down
12 changes: 6 additions & 6 deletions Assets/Mirror/Runtime/Transport/Websocket/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Mirror.Websocket
public class Client
{
public event Action Connected;
public event Action<byte[]> ReceivedData;
public event Action<ArraySegment<byte>> ReceivedData;
public event Action Disconnected;
public event Action<Exception> ReceivedError;

Expand Down Expand Up @@ -97,9 +97,9 @@ async Task ReceiveLoop(WebSocket webSocket, CancellationToken token)
break;

// we got a text or binary message, need the full message
byte[] data = await ReadFrames(result, webSocket, buffer);
ArraySegment<byte> data = await ReadFrames(result, webSocket, buffer);

if (data == null)
if (data.Count == 0)
break;

try
Expand All @@ -115,7 +115,7 @@ async Task ReceiveLoop(WebSocket webSocket, CancellationToken token)

// a message might come splitted in multiple frames
// collect all frames
async Task<byte[]> ReadFrames(WebSocketReceiveResult result, WebSocket webSocket, byte[] buffer)
async Task<ArraySegment<byte>> ReadFrames(WebSocketReceiveResult result, WebSocket webSocket, byte[] buffer)
{
int count = result.Count;

Expand All @@ -126,14 +126,14 @@ async Task<byte[]> ReadFrames(WebSocketReceiveResult result, WebSocket webSocket
string closeMessage = string.Format("Maximum message size: {0} bytes.", MaxMessageSize);
await webSocket.CloseAsync(WebSocketCloseStatus.MessageTooBig, closeMessage, CancellationToken.None);
ReceivedError?.Invoke(new WebSocketException(WebSocketError.HeaderError));
return null;
return new ArraySegment<byte>();
}

result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer, count, MaxMessageSize - count), CancellationToken.None);
count += result.Count;

}
return new ArraySegment<byte>(buffer, 0, count).ToArray();
return new ArraySegment<byte>(buffer, 0, count);
}

public void Disconnect()
Expand Down
4 changes: 2 additions & 2 deletions Assets/Mirror/Runtime/Transport/Websocket/ClientJs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class Client
public bool NoDelay = true;

public event Action Connected;
public event Action<byte[]> ReceivedData;
public event Action<ArraySegment<byte>> ReceivedData;
public event Action Disconnected;
public event Action<Exception> ReceivedError;

Expand Down Expand Up @@ -109,7 +109,7 @@ public static void OnData(int id, IntPtr ptr, int length)
byte[] data = new byte[length];
Marshal.Copy(ptr, data, 0, length);

clients[id].ReceivedData(data);
clients[id].ReceivedData(new ArraySegment<byte>(data));
}
#endregion
}
Expand Down
12 changes: 6 additions & 6 deletions Assets/Mirror/Runtime/Transport/Websocket/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Mirror.Websocket
public class Server
{
public event Action<int> Connected;
public event Action<int, byte[]> ReceivedData;
public event Action<int, ArraySegment<byte>> ReceivedData;
public event Action<int> Disconnected;
public event Action<int, Exception> ReceivedError;

Expand Down Expand Up @@ -196,9 +196,9 @@ async Task ReceiveLoopAsync(WebSocket webSocket, CancellationToken token)
break;
}

byte[] data = await ReadFrames(connectionId, result, webSocket, buffer, token);
ArraySegment<byte> data = await ReadFrames(connectionId, result, webSocket, buffer, token);

if (data == null)
if (data.Count == 0)
break;

try
Expand Down Expand Up @@ -226,7 +226,7 @@ async Task ReceiveLoopAsync(WebSocket webSocket, CancellationToken token)

// a message might come splitted in multiple frames
// collect all frames
async Task<byte[]> ReadFrames(int connectionId, WebSocketReceiveResult result, WebSocket webSocket, byte[] buffer, CancellationToken token)
async Task<ArraySegment<byte>> ReadFrames(int connectionId, WebSocketReceiveResult result, WebSocket webSocket, byte[] buffer, CancellationToken token)
{
int count = result.Count;

Expand All @@ -237,14 +237,14 @@ async Task<byte[]> ReadFrames(int connectionId, WebSocketReceiveResult result, W
string closeMessage = string.Format("Maximum message size: {0} bytes.", MaxMessageSize);
await webSocket.CloseAsync(WebSocketCloseStatus.MessageTooBig, closeMessage, CancellationToken.None);
ReceivedError?.Invoke(connectionId, new WebSocketException(WebSocketError.HeaderError));
return null;
return new ArraySegment<byte>();
}

result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer, count, MaxMessageSize - count), CancellationToken.None);
count += result.Count;

}
return new ArraySegment<byte>(buffer, 0, count).ToArray();
return new ArraySegment<byte>(buffer, 0, count);
}

public void Stop()
Expand Down

0 comments on commit 77bee45

Please sign in to comment.