breaking: remove batchInterval to prepare for TickBatching and for the scene change fix

This commit is contained in:
vis2k 2021-06-09 12:56:09 +08:00
parent 24130d6e35
commit 6e448f22f7
12 changed files with 35 additions and 91 deletions

View File

@ -10,7 +10,7 @@ class LocalConnectionToClient : NetworkConnectionToClient
{
internal LocalConnectionToServer connectionToServer;
public LocalConnectionToClient() : base(LocalConnectionId, false, 0) {}
public LocalConnectionToClient() : base(LocalConnectionId, false) {}
public override string address => "localhost";

View File

@ -23,34 +23,16 @@ internal class Batch
// IMPORTANT: we queue the serialized messages!
// queueing NetworkMessage would box and allocate!
internal Queue<PooledNetworkWriter> messages = new Queue<PooledNetworkWriter>();
// each channel's batch has its own lastSendTime.
// (use NetworkTime for maximum precision over days)
//
// channel batches are full and flushed at different times. using
// one global time wouldn't make sense.
// -> we want to be able to reset a channels send time after Send()
// flushed it because full. global time wouldn't allow that, so
// we would often flush in Send() and then flush again in Update
// even though we just flushed in Send().
// -> initialize with current NetworkTime so first update doesn't
// calculate elapsed via 'now - 0'
internal double lastSendTime = NetworkTime.time;
}
Dictionary<int, Batch> batches = new Dictionary<int, Batch>();
// batch messages and send them out in LateUpdate (or after batchInterval)
bool batching;
// batch interval is 0 by default, meaning that we send immediately.
// (useful to run tests without waiting for intervals too)
float batchInterval;
public NetworkConnectionToClient(int networkConnectionId, bool batching, float batchInterval)
public NetworkConnectionToClient(int networkConnectionId, bool batching)
: base(networkConnectionId)
{
this.batching = batching;
this.batchInterval = batchInterval;
}
Batch GetBatchForChannelId(int channelId)
@ -119,9 +101,6 @@ internal void SendBatch(int channelId, Batch batch)
writer.Position = 0;
}
}
// reset send time for this channel's batch
batch.lastSendTime = NetworkTime.time;
}
internal override void Send(ArraySegment<byte> segment, int channelId = Channels.Reliable)
@ -161,12 +140,10 @@ internal void Update()
// go through batches for all channels
foreach (KeyValuePair<int, Batch> kvp in batches)
{
// enough time elapsed to flush this channel's batch?
// and not empty?
double elapsed = NetworkTime.time - kvp.Value.lastSendTime;
if (elapsed >= batchInterval && kvp.Value.messages.Count > 0)
// is this channel's batch not empty?
if (kvp.Value.messages.Count > 0)
{
// send the batch. time will be reset internally.
// send the batch.
//Debug.Log($"sending batch of {kvp.Value.writer.Position} bytes for channel={kvp.Key} connId={connectionId}");
SendBatch(kvp.Key, kvp.Value);
}

View File

@ -49,10 +49,6 @@ public class NetworkManager : MonoBehaviour
[Tooltip("Batch message and send them out in LateUpdate (or after batchInterval). This is pretty much always a good idea.")]
public bool serverBatching = true;
/// <summary>Server can batch messages to significantly reduce transport calls and improve performance/scale.</summary>
[Tooltip("Server can batch messages up to Transport.GetMaxPacketSize to significantly reduce transport calls and improve performance/scale.\nIf batch interval is 0, then we only batch until the Update() call. Otherwise we batch until interval elapsed (note that this increases latency).")]
public float serverBatchInterval = 0;
/// <summary>Automatically switch to this scene upon going offline (on start / on disconnect / on shutdown).</summary>
[Header("Scene Management")]
[Scene]
@ -252,7 +248,6 @@ void SetupServer()
// batching
NetworkServer.batching = serverBatching;
NetworkServer.batchInterval = serverBatchInterval;
// Copy auto-disconnect settings to NetworkServer
#pragma warning disable 618

View File

@ -37,9 +37,6 @@ public static class NetworkServer
// (this is pretty much always a good idea)
public static bool batching = true;
/// <summary>interval in seconds used for batching. 0 means send in every LateUpdate.</summary>
public static float batchInterval = 0;
// interest management component (optional)
// by default, everyone observes everyone
public static InterestManagement aoi;
@ -383,7 +380,7 @@ static void OnTransportConnected(int connectionId)
if (connections.Count < maxConnections)
{
// add connection
NetworkConnectionToClient conn = new NetworkConnectionToClient(connectionId, batching, batchInterval);
NetworkConnectionToClient conn = new NetworkConnectionToClient(connectionId, batching);
OnConnected(conn);
}
else

View File

@ -4,7 +4,7 @@ namespace Mirror.Tests
{
public class FakeNetworkConnection : NetworkConnectionToClient
{
public FakeNetworkConnection() : base(1, false, 0)
public FakeNetworkConnection() : base(1, false)
{
}

View File

@ -21,7 +21,7 @@ public override void SetUp()
transport.serverIncoming.Clear();
// need a connection to client with batching enabled
connection = new NetworkConnectionToClient(42, true, 0);
connection = new NetworkConnectionToClient(42, true);
// need a batch too
batch = new NetworkConnectionToClient.Batch();

View File

@ -21,7 +21,7 @@ public override void SetUp()
// A with connectionId = 0x0A, netId = 0xAA
CreateNetworked(out gameObjectA, out identityA);
connectionA = new NetworkConnectionToClient(0x0A, false, 0);
connectionA = new NetworkConnectionToClient(0x0A, false);
connectionA.isAuthenticated = true;
connectionA.isReady = true;
connectionA.identity = identityA;
@ -29,7 +29,7 @@ public override void SetUp()
// B
CreateNetworked(out gameObjectB, out identityB);
connectionB = new NetworkConnectionToClient(0x0B, false, 0);
connectionB = new NetworkConnectionToClient(0x0B, false);
connectionB.isAuthenticated = true;
connectionB.isReady = true;
connectionB.identity = identityB;

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Threading;
using NUnit.Framework;
namespace Mirror.Tests
@ -35,7 +34,7 @@ public override void TearDown()
public void Send_WithoutBatching_SendsImmediately()
{
// create connection and send
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, false, 0);
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, false);
byte[] message = {0x01, 0x02};
connection.Send(new ArraySegment<byte>(message));
@ -48,7 +47,7 @@ public void Send_WithoutBatching_SendsImmediately()
public void Send_BatchesUntilUpdate()
{
// create connection and send
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, true, 0);
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, true);
byte[] message = {0x01, 0x02};
connection.Send(new ArraySegment<byte>(message));
@ -62,30 +61,6 @@ public void Send_BatchesUntilUpdate()
Assert.That(clientReceived.Count, Is.EqualTo(1));
}
[Test]
public void Send_BatchesUntilInterval()
{
// create connection and send
int intervalMilliseconds = 10;
float intervalSeconds = intervalMilliseconds / 1000f;
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, true, intervalSeconds);
byte[] message = {0x01, 0x02};
connection.Send(new ArraySegment<byte>(message));
// Send() and update shouldn't send yet until interval elapsed
connection.Update();
UpdateTransport();
Assert.That(clientReceived.Count, Is.EqualTo(0));
// wait 'interval'
Thread.Sleep(intervalMilliseconds);
// updating again should flush out the batch
connection.Update();
UpdateTransport();
Assert.That(clientReceived.Count, Is.EqualTo(1));
}
// IMPORTANT
//
// there was a bug where batching resets .Position instead of .Length,
@ -97,7 +72,7 @@ public void Send_BatchesUntilInterval()
public void SendBatchingResetsPreviousWriter()
{
// create connection
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, true, 0);
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, true);
// send and update big message
byte[] message = {0x01, 0x02};

View File

@ -425,11 +425,11 @@ public void RemoveObserverInternal()
identity.OnStartServer();
// add an observer connection
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, false, 0);
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, false);
identity.observers[connection.connectionId] = connection;
// RemoveObserverInternal with invalid connection should do nothing
identity.RemoveObserverInternal(new NetworkConnectionToClient(43, false, 0));
identity.RemoveObserverInternal(new NetworkConnectionToClient(43, false));
Assert.That(identity.observers.Count, Is.EqualTo(1));
// RemoveObserverInternal with existing connection should remove it
@ -635,7 +635,7 @@ public void AssignAndRemoveClientAuthority()
// another connection
// error log is expected
LogAssert.ignoreFailingMessages = true;
result = identity.AssignClientAuthority(new NetworkConnectionToClient(43, false, 0));
result = identity.AssignClientAuthority(new NetworkConnectionToClient(43, false));
LogAssert.ignoreFailingMessages = false;
Assert.That(result, Is.False);
Assert.That(identity.connectionToClient, Is.EqualTo(owner));
@ -1000,8 +1000,8 @@ public void AddObserver()
CreateNetworked(out GameObject _, out NetworkIdentity identity);
// create some connections
NetworkConnectionToClient connection1 = new NetworkConnectionToClient(42, false, 0);
NetworkConnectionToClient connection2 = new NetworkConnectionToClient(43, false, 0);
NetworkConnectionToClient connection1 = new NetworkConnectionToClient(42, false);
NetworkConnectionToClient connection2 = new NetworkConnectionToClient(43, false);
// AddObserver should return early if called before .observers was
// created
@ -1025,7 +1025,7 @@ public void AddObserver()
Assert.That(identity.observers[connection2.connectionId], Is.EqualTo(connection2));
// adding a duplicate connectionId shouldn't overwrite the original
NetworkConnectionToClient duplicate = new NetworkConnectionToClient(connection1.connectionId, false, 0);
NetworkConnectionToClient duplicate = new NetworkConnectionToClient(connection1.connectionId, false);
identity.AddObserver(duplicate);
Assert.That(identity.observers.Count, Is.EqualTo(2));
Assert.That(identity.observers.ContainsKey(connection1.connectionId));
@ -1043,8 +1043,8 @@ public void ClearObservers()
identity.OnStartServer();
// add some observers
identity.observers[42] = new NetworkConnectionToClient(42, false, 0);
identity.observers[43] = new NetworkConnectionToClient(43, false, 0);
identity.observers[42] = new NetworkConnectionToClient(42, false);
identity.observers[43] = new NetworkConnectionToClient(43, false);
// call ClearObservers
identity.ClearObservers();
@ -1124,9 +1124,9 @@ public void Reset()
identity.isClient = true;
// creates .observers and generates a netId
identity.OnStartServer();
identity.connectionToClient = new NetworkConnectionToClient(1, false, 0);
identity.connectionToClient = new NetworkConnectionToClient(1, false);
identity.connectionToServer = new NetworkConnectionToServer();
identity.observers[43] = new NetworkConnectionToClient(2, false, 0);
identity.observers[43] = new NetworkConnectionToClient(2, false);
// mark for reset and reset
identity.Reset();
@ -1141,7 +1141,7 @@ public void HandleCommand()
{
CreateNetworked(out GameObject _, out NetworkIdentity identity, out CommandTestNetworkBehaviour comp0);
NetworkConnectionToClient connection = new NetworkConnectionToClient(1, false, 0);
NetworkConnectionToClient connection = new NetworkConnectionToClient(1, false);
Assert.That(comp0.called, Is.EqualTo(0));
Assert.That(comp0.senderConnectionInCall, Is.Null);

View File

@ -43,7 +43,7 @@ public override void SetUp()
static NetworkConnection CreateNetworkConnection(GameObject player)
{
NetworkConnectionToClient connection = new NetworkConnectionToClient(++nextConnectionId, false, 0);
NetworkConnectionToClient connection = new NetworkConnectionToClient(++nextConnectionId, false);
connection.identity = player.GetComponent<NetworkIdentity>();
connection.identity.connectionToClient = connection;
connection.identity.observers = new Dictionary<int, NetworkConnection>();

View File

@ -288,7 +288,7 @@ public void AddConnection()
Assert.That(NetworkServer.connections.Count, Is.EqualTo(0));
// add first connection
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42, false, 0);
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42, false);
bool result42 = NetworkServer.AddConnection(conn42);
Assert.That(result42, Is.True);
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
@ -296,7 +296,7 @@ public void AddConnection()
Assert.That(NetworkServer.connections[42], Is.EqualTo(conn42));
// add second connection
NetworkConnectionToClient conn43 = new NetworkConnectionToClient(43, false, 0);
NetworkConnectionToClient conn43 = new NetworkConnectionToClient(43, false);
bool result43 = NetworkServer.AddConnection(conn43);
Assert.That(result43, Is.True);
Assert.That(NetworkServer.connections.Count, Is.EqualTo(2));
@ -306,7 +306,7 @@ public void AddConnection()
Assert.That(NetworkServer.connections[43], Is.EqualTo(conn43));
// add duplicate connectionId
NetworkConnectionToClient connDup = new NetworkConnectionToClient(42, false, 0);
NetworkConnectionToClient connDup = new NetworkConnectionToClient(42, false);
bool resultDup = NetworkServer.AddConnection(connDup);
Assert.That(resultDup, Is.False);
Assert.That(NetworkServer.connections.Count, Is.EqualTo(2));
@ -324,7 +324,7 @@ public void RemoveConnection()
Assert.That(NetworkServer.connections.Count, Is.EqualTo(0));
// add connection
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42, false, 0);
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42, false);
bool result42 = NetworkServer.AddConnection(conn42);
Assert.That(result42, Is.True);
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
@ -345,7 +345,7 @@ public void DisconnectAllTest_RemoteConnection()
Assert.That(NetworkServer.connections.Count, Is.EqualTo(0));
// add connection
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42, false, 0);
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42, false);
NetworkServer.AddConnection(conn42);
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
@ -371,7 +371,7 @@ public void DisconnectAllTest_LocalConnection()
Assert.That(NetworkServer.localConnection, Is.EqualTo(localConnection));
// add connection
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42, false, 0);
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42, false);
NetworkServer.AddConnection(conn42);
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
@ -400,7 +400,7 @@ public void OnDataReceived()
Assert.That(NetworkServer.connections.Count, Is.EqualTo(0));
// add a connection
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, false, 0);
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, false);
NetworkServer.AddConnection(connection);
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
@ -687,7 +687,7 @@ public void RegisterUnregisterClearHandler()
Assert.That(NetworkServer.connections.Count, Is.EqualTo(0));
// add a connection
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, false, 0);
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, false);
NetworkServer.AddConnection(connection);
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));

View File

@ -33,7 +33,7 @@ public override IEnumerator UnityTearDown()
public IEnumerator DestroyPlayerForConnectionTest()
{
GameObject player = new GameObject("testPlayer", typeof(NetworkIdentity));
NetworkConnectionToClient conn = new NetworkConnectionToClient(1, false, 0);
NetworkConnectionToClient conn = new NetworkConnectionToClient(1, false);
NetworkServer.AddPlayerForConnection(conn, player);
@ -52,7 +52,7 @@ public IEnumerator DestroyPlayerForConnectionTest()
public IEnumerator RemovePlayerForConnectionTest()
{
GameObject player = new GameObject("testPlayer", typeof(NetworkIdentity));
NetworkConnectionToClient conn = new NetworkConnectionToClient(1, false, 0);
NetworkConnectionToClient conn = new NetworkConnectionToClient(1, false);
NetworkServer.AddPlayerForConnection(conn, player);