mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
perf: Adding buffer for local connection (#1621)
* Using writer for local connection LocalConnectionBuffer * removing assert * fixing error and cleaning up code * removing old queue * tests for LocalConnectionBuffer * removing field * removing extra lines * Update LocalConnections.cs removing empty line * adding comment for packet count
This commit is contained in:
parent
0ee5d52964
commit
4d5cee893d
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mirror
|
||||
@ -18,11 +17,8 @@ public ULocalConnectionToClient() : base(0)
|
||||
|
||||
internal override bool Send(ArraySegment<byte> segment, int channelId = Channels.DefaultReliable)
|
||||
{
|
||||
// LocalConnection doesn't support allocation-free sends yet.
|
||||
// previously we allocated in Mirror. now we do it here.
|
||||
byte[] data = new byte[segment.Count];
|
||||
Array.Copy(segment.Array, segment.Offset, data, 0, segment.Count);
|
||||
connectionToServer.packetQueue.Enqueue(data);
|
||||
connectionToServer.buffer.Write(segment);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -44,16 +40,48 @@ public override void Disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
internal class LocalConnectionBuffer
|
||||
{
|
||||
readonly NetworkWriter writer = new NetworkWriter();
|
||||
readonly NetworkReader reader = new NetworkReader(default(ArraySegment<byte>));
|
||||
// The buffer is atleast 1500 bytes long. So need to keep track of
|
||||
// packet count to know how many ArraySegments are in the buffer
|
||||
int packetCount;
|
||||
|
||||
public void Write(ArraySegment<byte> segment)
|
||||
{
|
||||
writer.WriteBytesAndSizeSegment(segment);
|
||||
packetCount++;
|
||||
|
||||
// update buffer incase writer's length has changed
|
||||
reader.buffer = writer.ToArraySegment();
|
||||
}
|
||||
|
||||
public bool HasPackets()
|
||||
{
|
||||
return packetCount > 0;
|
||||
}
|
||||
public ArraySegment<byte> GetNextPacket()
|
||||
{
|
||||
ArraySegment<byte> packet = reader.ReadBytesAndSizeSegment();
|
||||
packetCount--;
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
public void ResetBuffer()
|
||||
{
|
||||
writer.SetLength(0);
|
||||
reader.Position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// a localClient's connection TO a server.
|
||||
// send messages on this connection causes the server's handler function to be invoked directly.
|
||||
internal class ULocalConnectionToServer : NetworkConnectionToServer
|
||||
{
|
||||
internal ULocalConnectionToClient connectionToClient;
|
||||
|
||||
// local client in host mode might call Cmds/Rpcs during Update, but we
|
||||
// want to apply them in LateUpdate like all other Transport messages
|
||||
// to avoid race conditions. keep packets in Queue until LateUpdate.
|
||||
internal Queue<byte[]> packetQueue = new Queue<byte[]>();
|
||||
internal readonly LocalConnectionBuffer buffer = new LocalConnectionBuffer();
|
||||
|
||||
public override string address => "localhost";
|
||||
|
||||
@ -73,13 +101,16 @@ internal override bool Send(ArraySegment<byte> segment, int channelId = Channels
|
||||
internal void Update()
|
||||
{
|
||||
// process internal messages so they are applied at the correct time
|
||||
while (packetQueue.Count > 0)
|
||||
while (buffer.HasPackets())
|
||||
{
|
||||
byte[] packet = packetQueue.Dequeue();
|
||||
ArraySegment<byte> packet = buffer.GetNextPacket();
|
||||
|
||||
// Treat host player messages exactly like connected client
|
||||
// to avoid deceptive / misleading behavior differences
|
||||
TransportReceive(new ArraySegment<byte>(packet), Channels.DefaultReliable);
|
||||
TransportReceive(packet, Channels.DefaultReliable);
|
||||
}
|
||||
|
||||
buffer.ResetBuffer();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
142
Assets/Mirror/Tests/Editor/LocalConnectionBufferTest.cs
Normal file
142
Assets/Mirror/Tests/Editor/LocalConnectionBufferTest.cs
Normal file
@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Mirror.Tests
|
||||
{
|
||||
public class LocalConnectionBufferTest
|
||||
{
|
||||
readonly LocalConnectionBuffer buffer = new LocalConnectionBuffer();
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
buffer.ResetBuffer();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BufferHasPacketsAfterWriter()
|
||||
{
|
||||
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
|
||||
{
|
||||
writer.WriteString("Some Message");
|
||||
|
||||
buffer.Write(writer.ToArraySegment());
|
||||
}
|
||||
|
||||
Assert.IsTrue(buffer.HasPackets());
|
||||
}
|
||||
[Test]
|
||||
public void BufferHasNoPacketsAfterWriteAndReading()
|
||||
{
|
||||
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
|
||||
{
|
||||
writer.WriteString("Some Message");
|
||||
|
||||
buffer.Write(writer.ToArraySegment());
|
||||
}
|
||||
ArraySegment<byte> package = buffer.GetNextPacket();
|
||||
|
||||
|
||||
Assert.IsFalse(buffer.HasPackets());
|
||||
}
|
||||
[Test]
|
||||
public void BufferCanWriteAndReadPackages()
|
||||
{
|
||||
const string expectedMessage = "Some Message";
|
||||
const float expectedValue = 46.8f;
|
||||
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
|
||||
{
|
||||
writer.WriteString(expectedMessage);
|
||||
writer.WriteSingle(expectedValue);
|
||||
|
||||
buffer.Write(writer.ToArraySegment());
|
||||
}
|
||||
ArraySegment<byte> package = buffer.GetNextPacket();
|
||||
|
||||
string message;
|
||||
float value;
|
||||
using (PooledNetworkReader reader = NetworkReaderPool.GetReader(package))
|
||||
{
|
||||
message = reader.ReadString();
|
||||
value = reader.ReadSingle();
|
||||
}
|
||||
|
||||
Assert.That(message, Is.EqualTo(expectedMessage));
|
||||
Assert.That(value, Is.EqualTo(expectedValue));
|
||||
}
|
||||
[Test]
|
||||
public void BufferReturnsMutliplePacketsInTheOrderTheyWereWriten()
|
||||
{
|
||||
const string expectedMessage1 = "first Message";
|
||||
const string expectedMessage2 = "second Message";
|
||||
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
|
||||
{
|
||||
writer.WriteString(expectedMessage1);
|
||||
|
||||
buffer.Write(writer.ToArraySegment());
|
||||
}
|
||||
|
||||
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
|
||||
{
|
||||
writer.WriteString(expectedMessage2);
|
||||
|
||||
buffer.Write(writer.ToArraySegment());
|
||||
}
|
||||
|
||||
string message1;
|
||||
string message2;
|
||||
ArraySegment<byte> package1 = buffer.GetNextPacket();
|
||||
|
||||
using (PooledNetworkReader reader = NetworkReaderPool.GetReader(package1))
|
||||
{
|
||||
message1 = reader.ReadString();
|
||||
}
|
||||
|
||||
Assert.IsTrue(buffer.HasPackets());
|
||||
ArraySegment<byte> package2 = buffer.GetNextPacket();
|
||||
|
||||
using (PooledNetworkReader reader = NetworkReaderPool.GetReader(package2))
|
||||
{
|
||||
message2 = reader.ReadString();
|
||||
}
|
||||
|
||||
Assert.That(message1, Is.EqualTo(expectedMessage1));
|
||||
Assert.That(message2, Is.EqualTo(expectedMessage2));
|
||||
}
|
||||
[Test]
|
||||
public void BufferCanWriteReadMorePackageAfterCallingReset()
|
||||
{
|
||||
const string expectedMessage = "Some Message";
|
||||
const float expectedValue = 46.8f;
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
|
||||
{
|
||||
writer.WriteInt32(i);
|
||||
writer.WriteString(expectedMessage);
|
||||
writer.WriteSingle(expectedValue);
|
||||
|
||||
buffer.Write(writer.ToArraySegment());
|
||||
}
|
||||
ArraySegment<byte> package = buffer.GetNextPacket();
|
||||
|
||||
int index;
|
||||
string message;
|
||||
float value;
|
||||
using (PooledNetworkReader reader = NetworkReaderPool.GetReader(package))
|
||||
{
|
||||
index = reader.ReadInt32();
|
||||
message = reader.ReadString();
|
||||
value = reader.ReadSingle();
|
||||
}
|
||||
|
||||
Assert.That(index, Is.EqualTo(i));
|
||||
Assert.That(message, Is.EqualTo(expectedMessage));
|
||||
Assert.That(value, Is.EqualTo(expectedValue));
|
||||
|
||||
buffer.ResetBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Mirror/Tests/Editor/LocalConnectionBufferTest.cs.meta
Normal file
11
Assets/Mirror/Tests/Editor/LocalConnectionBufferTest.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e035d8111975b864099f87f21c5518ff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Reference in New Issue
Block a user