bidirectional acks & tracking

This commit is contained in:
mischa 2024-07-20 15:40:16 +02:00
parent b6e4e595dd
commit 025a49ca4c
2 changed files with 32 additions and 0 deletions

View File

@ -115,6 +115,13 @@ public static partial class NetworkClient
internal static Unbatcher unbatcher = new Unbatcher();
// unreliable delta compression:
// define how much of a state history we should track for acks.
// for example: 60 Hz * 3s = 180 entries.
// the history is per-connection, so we don't want to make this too large.
public static int tickHistorySeconds = 3;
public static int tickHistorySize => sendRate * tickHistorySeconds;
// interest management component (optional)
// only needed for SetHostVisibility
public static InterestManagementBase aoi;
@ -515,6 +522,7 @@ internal static void RegisterMessageHandlers(bool hostMode)
// host mode doesn't need state updates
RegisterHandler<EntityStateMessage>(_ => { });
RegisterHandler<EntityStateMessageUnreliable>(_ => { });
RegisterHandler<AckMessage>(_ => { }, false);
}
else
{
@ -527,6 +535,7 @@ internal static void RegisterMessageHandlers(bool hostMode)
RegisterHandler<ObjectSpawnFinishedMessage>(OnObjectSpawnFinished);
RegisterHandler<EntityStateMessage>(OnEntityStateMessage);
RegisterHandler<EntityStateMessageUnreliable>(OnEntityStateMessageUnreliable);
RegisterHandler<AckMessage>(OnAckMessage, false);
}
// These handlers are the same for host and remote clients
@ -1508,6 +1517,16 @@ internal static void ChangeOwner(NetworkIdentity identity, ChangeOwnerMessage me
}
}
// ack delta compression ///////////////////////////////////////////////
static void OnAckMessage(AckMessage message)
{
// for the acknowledged batch's timestamp:
// update last ack for all NetworkIdentities that were in the batch.
// Debug.Log($"NetworkServer received acknowledgement: {message.batchTimestamp} for connId={connection.connectionId}");
AckDeltaCompression.UpdateIdentityAcks(message.batchTimestamp, connection.identityTicks, connection.identityAcks);
}
// spawning ////////////////////////////////////////////////////////////
// set up NetworkIdentity flags on the client.
// needs to be separate from invoking callbacks.
// cleaner, and some places need to set flags first.
@ -1611,6 +1630,10 @@ static void Broadcast()
payload = writer.ToArraySegment()
};
Send(message, Channels.Unreliable);
// keep track of which entities we sent to the connection on this tick.
// so when the connection sends back an ack, we know which entities were acked.
AckDeltaCompression.TrackIdentityAtTick(NetworkTime.localTime, identity.netId, connection.identityTicks, tickHistorySize);
}
}
}

View File

@ -904,6 +904,15 @@ internal static void OnTransportData(int connectionId, ArraySegment<byte> data,
{
Debug.LogError($"Still had {connection.unbatcher.BatchesCount} batches remaining after processing, even though processing was not interrupted by a scene change. This should never happen, as it would cause ever growing batches.\nPossible reasons:\n* A message didn't deserialize as much as it serialized\n*There was no message handler for a message id, so the reader wasn't read until the end.");
}
// FastPaced unreliable sync:
// always acknowledge the last received batch so the other end
// knows what to delta compress against.
if (channelId == Channels.Unreliable)
{
// Debug.Log($"NetworkServer: acknowledging batch {connection.remoteTimeStamp}");
connection.Send(new AckMessage{batchTimestamp = connection.remoteTimeStamp}, Channels.Unreliable);
}
}
else Debug.LogError($"HandleData Unknown connectionId:{connectionId}");
}