LocalConnections.LocalConnectionBuffer replaced with System.Queue (#2585)

This commit is contained in:
vis2k 2021-02-18 14:56:46 +08:00 committed by GitHub
parent 73d95f9b5b
commit b09d1681a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 199 deletions

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
namespace Mirror namespace Mirror
@ -15,7 +16,15 @@ public LocalConnectionToClient() : base(LocalConnectionId, false, 0) {}
internal override void Send(ArraySegment<byte> segment, int channelId = Channels.DefaultReliable) internal override void Send(ArraySegment<byte> segment, int channelId = Channels.DefaultReliable)
{ {
connectionToServer.buffer.Write(segment); // get a writer to copy the message into since the segment is only
// valid until returning.
// => pooled writer will be returned to pool when dequeuing.
// => WriteBytes instead of WriteArraySegment because the latter
// includes a 4 bytes header. we just want to write raw.
//Debug.Log("Enqueue " + BitConverter.ToString(segment.Array, segment.Offset, segment.Count));
PooledNetworkWriter writer = NetworkWriterPool.GetWriter();
writer.WriteBytes(segment.Array, segment.Offset, segment.Count);
connectionToServer.queue.Enqueue(writer);
} }
// true because local connections never timeout // true because local connections never timeout
@ -40,48 +49,14 @@ public override void Disconnect()
} }
} }
internal class LocalConnectionBuffer
{
readonly NetworkWriter writer = new NetworkWriter();
readonly NetworkReader reader = new NetworkReader(default(ArraySegment<byte>));
// The buffer is at least 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 in case 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.Reset();
reader.Position = 0;
}
}
// a localClient's connection TO a server. // a localClient's connection TO a server.
// send messages on this connection causes the server's handler function to be invoked directly. // send messages on this connection causes the server's handler function to be invoked directly.
internal class LocalConnectionToServer : NetworkConnectionToServer internal class LocalConnectionToServer : NetworkConnectionToServer
{ {
internal LocalConnectionToClient connectionToClient; internal LocalConnectionToClient connectionToClient;
internal readonly LocalConnectionBuffer buffer = new LocalConnectionBuffer();
// packet queue
internal readonly Queue<PooledNetworkWriter> queue = new Queue<PooledNetworkWriter>();
public override string address => "localhost"; public override string address => "localhost";
@ -113,17 +88,16 @@ internal void Update()
} }
// process internal messages so they are applied at the correct time // process internal messages so they are applied at the correct time
while (buffer.HasPackets()) while (queue.Count > 0)
{ {
ArraySegment<byte> packet = buffer.GetNextPacket(); // call receive on queued writer's content, return to pool
PooledNetworkWriter writer = queue.Dequeue();
// Treat host player messages exactly like connected client ArraySegment<byte> segment = writer.ToArraySegment();
// to avoid deceptive / misleading behavior differences //Debug.Log("Dequeue " + BitConverter.ToString(segment.Array, segment.Offset, segment.Count));
TransportReceive(packet, Channels.DefaultReliable); TransportReceive(segment, Channels.DefaultReliable);
NetworkWriterPool.Recycle(writer);
} }
buffer.ResetBuffer();
// should we still process a disconnected event? // should we still process a disconnected event?
if (disconnectedEventPending) if (disconnectedEventPending)
{ {

View File

@ -1,142 +0,0 @@
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();
}
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: e035d8111975b864099f87f21c5518ff
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: