Skip to content

Commit 026b748

Browse files
author
JS Fauteux
authored
feat: UTP Packet Loss tracking [MTT-1654] (#1833)
* feat: UTP Packet Loss tracking [MTT-1654] * Added missing ifdef, and changed name to better reflect the value given * Dispatching percentage as not multiplied by 100 (value between 0 and 1) * Tweaked test to use constants * Updated reference for tools in testproject-tools-integration * Fix whitespace
1 parent e93398a commit 026b748

File tree

7 files changed

+147
-6
lines changed

7 files changed

+147
-6
lines changed

com.unity.netcode.gameobjects/Runtime/Metrics/INetworkMetrics.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,14 @@ void TrackRpcReceived(
8787

8888
void TrackPacketReceived(uint packetCount);
8989

90-
void TrackRttToServer(int rtt);
90+
void UpdateRttToServer(int rtt);
9191

9292
void UpdateNetworkObjectsCount(int count);
9393

9494
void UpdateConnectionsCount(int count);
9595

96+
void UpdatePacketLoss(float packetLoss);
97+
9698
void DispatchFrame();
9799
}
98100
}

com.unity.netcode.gameobjects/Runtime/Metrics/NetworkMetrics.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ private static string GetSceneEventTypeName(uint typeCode)
8787
{
8888
ShouldResetOnDispatch = true,
8989
};
90+
private readonly Gauge m_PacketLossGauge = new Gauge(NetworkMetricTypes.PacketLoss.Id);
9091
#endif
9192

9293
private ulong m_NumberOfMetricsThisFrame;
@@ -110,6 +111,7 @@ public NetworkMetrics()
110111
.WithGauges(m_RttToServerGauge)
111112
.WithGauges(m_NetworkObjectsGauge)
112113
.WithGauges(m_ConnectionsGauge)
114+
.WithGauges(m_PacketLossGauge)
113115
#endif
114116
.Build();
115117

@@ -462,7 +464,7 @@ public void TrackPacketReceived(uint packetCount)
462464
#endif
463465
}
464466

465-
public void TrackRttToServer(int rttMilliseconds)
467+
public void UpdateRttToServer(int rttMilliseconds)
466468
{
467469
#if MULTIPLAYER_TOOLS_1_0_0_PRE_7
468470
if (!CanSendMetrics)
@@ -498,6 +500,18 @@ public void UpdateConnectionsCount(int count)
498500
#endif
499501
}
500502

503+
public void UpdatePacketLoss(float packetLoss)
504+
{
505+
#if MULTIPLAYER_TOOLS_1_0_0_PRE_7
506+
if (!CanSendMetrics)
507+
{
508+
return;
509+
}
510+
511+
m_PacketLossGauge.Set(packetLoss);
512+
#endif
513+
}
514+
501515
public void DispatchFrame()
502516
{
503517
s_FrameDispatch.Begin();

com.unity.netcode.gameobjects/Runtime/Metrics/NullNetworkMetrics.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public void TrackPacketReceived(uint packetCount)
145145
{
146146
}
147147

148-
public void TrackRttToServer(int rtt)
148+
public void UpdateRttToServer(int rtt)
149149
{
150150
}
151151

@@ -157,6 +157,10 @@ public void UpdateConnectionsCount(int count)
157157
{
158158
}
159159

160+
public void UpdatePacketLoss(float packetLoss)
161+
{
162+
}
163+
160164
public void DispatchFrame()
161165
{
162166
}

com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,10 @@ private void ExtractNetworkMetricsForClient(ulong transportClientId)
710710
ExtractNetworkMetricsFromPipeline(m_ReliableSequencedPipeline, networkConnection);
711711

712712
var rttValue = NetworkManager.IsServer ? 0 : ExtractRtt(networkConnection);
713-
NetworkMetrics.TrackRttToServer(rttValue);
713+
NetworkMetrics.UpdateRttToServer(rttValue);
714+
715+
var packetLoss = NetworkManager.IsServer ? 0 : ExtractPacketLoss(networkConnection);
716+
NetworkMetrics.UpdatePacketLoss(packetLoss);
714717
}
715718

716719
private void ExtractNetworkMetricsFromPipeline(NetworkPipeline pipeline, NetworkConnection networkConnection)
@@ -758,6 +761,32 @@ private int ExtractRtt(NetworkConnection networkConnection)
758761
}
759762
}
760763

764+
private float ExtractPacketLoss(NetworkConnection networkConnection)
765+
{
766+
if (m_Driver.GetConnectionState(networkConnection) != NetworkConnection.State.Connected)
767+
{
768+
return 0f;
769+
}
770+
771+
m_Driver.GetPipelineBuffers(m_ReliableSequencedPipeline,
772+
NetworkPipelineStageCollection.GetStageId(typeof(ReliableSequencedPipelineStage)),
773+
networkConnection,
774+
out _,
775+
out _,
776+
out var sharedBuffer);
777+
778+
unsafe
779+
{
780+
var sharedContext = (ReliableUtility.SharedContext*)sharedBuffer.GetUnsafePtr();
781+
782+
var packetReceived = (float)sharedContext->stats.PacketsReceived;
783+
var packetDropped = (float)sharedContext->stats.PacketsDropped;
784+
var packetLoss = packetReceived > 0 ? packetDropped / packetReceived : 0;
785+
786+
return packetLoss;
787+
}
788+
}
789+
761790
private static unsafe ulong ParseClientId(NetworkConnection utpConnectionId)
762791
{
763792
return *(ulong*)&utpConnectionId;
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#if MULTIPLAYER_TOOLS
2+
#if MULTIPLAYER_TOOLS_1_0_0_PRE_7
3+
4+
using System;
5+
using System.Collections;
6+
using NUnit.Framework;
7+
using Unity.Collections;
8+
using Unity.Multiplayer.Tools.MetricTypes;
9+
using Unity.Netcode.TestHelpers.Runtime;
10+
using Unity.Netcode.TestHelpers.Runtime.Metrics;
11+
using Unity.Netcode.Transports.UTP;
12+
using UnityEngine;
13+
using UnityEngine.TestTools;
14+
15+
namespace Unity.Netcode.RuntimeTests.Metrics
16+
{
17+
public class PacketLossMetricsTests : NetcodeIntegrationTest
18+
{
19+
protected override int NumberOfClients => 1;
20+
private readonly int m_PacketLossRate = 25;
21+
private int m_DropInterval = 5;
22+
23+
public PacketLossMetricsTests()
24+
: base(HostOrServer.Server)
25+
{}
26+
27+
protected override void OnOneTimeSetup()
28+
{
29+
m_NetworkTransport = NetcodeIntegrationTestHelpers.InstanceTransport.UTP;
30+
}
31+
32+
protected override void OnServerAndClientsCreated()
33+
{
34+
var clientTransport = (UnityTransport)m_ClientNetworkManagers[0].NetworkConfig.NetworkTransport;
35+
clientTransport.SetDebugSimulatorParameters(0, 0, m_PacketLossRate);
36+
37+
base.OnServerAndClientsCreated();
38+
}
39+
40+
[UnityTest]
41+
public IEnumerator TrackPacketLossAsServer()
42+
{
43+
var waitForPacketLossMetric = new WaitForGaugeMetricValues((m_ServerNetworkManager.NetworkMetrics as NetworkMetrics).Dispatcher,
44+
NetworkMetricTypes.PacketLoss,
45+
metric => metric == 0.0d);
46+
47+
for (int i = 0; i < 1000; ++i)
48+
{
49+
using (var writer = new FastBufferWriter(sizeof(byte), Allocator.Persistent))
50+
{
51+
writer.WriteByteSafe(42);
52+
m_ServerNetworkManager.CustomMessagingManager.SendNamedMessage("Test", m_ServerNetworkManager.ConnectedClientsIds, writer);
53+
}
54+
}
55+
56+
yield return waitForPacketLossMetric.WaitForMetricsReceived();
57+
58+
var packetLossValue = waitForPacketLossMetric.AssertMetricValueHaveBeenFound();
59+
Assert.AreEqual(0d, packetLossValue);
60+
}
61+
62+
[UnityTest]
63+
public IEnumerator TrackPacketLossAsClient()
64+
{
65+
double packetLossRate = m_PacketLossRate/100d;
66+
var clientNetworkManager = m_ClientNetworkManagers[0];
67+
var waitForPacketLossMetric = new WaitForGaugeMetricValues((clientNetworkManager.NetworkMetrics as NetworkMetrics).Dispatcher,
68+
NetworkMetricTypes.PacketLoss,
69+
metric => Math.Abs(metric - packetLossRate) < Double.Epsilon);
70+
71+
for (int i = 0; i < 1000; ++i)
72+
{
73+
using (var writer = new FastBufferWriter(sizeof(byte), Allocator.Persistent))
74+
{
75+
writer.WriteByteSafe(42);
76+
m_ServerNetworkManager.CustomMessagingManager.SendNamedMessage("Test", m_ServerNetworkManager.ConnectedClientsIds, writer);
77+
}
78+
}
79+
80+
yield return waitForPacketLossMetric.WaitForMetricsReceived();
81+
82+
var packetLossValue = waitForPacketLossMetric.AssertMetricValueHaveBeenFound();
83+
Assert.AreEqual(packetLossRate, packetLossValue);
84+
}
85+
}
86+
}
87+
88+
#endif
89+
#endif

com.unity.netcode.gameobjects/Tests/Runtime/Metrics/PacketLossMetricsTests.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

testproject-tools-integration/Packages/manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"registry": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates",
33
"dependencies": {
44
"com.unity.ide.rider": "3.0.7",
5-
"com.unity.multiplayer.tools": "https://github.com/Unity-Technologies/com.unity.multiplayer.tools.git#cfb8fd305c3e46bb1251b40ec5f6cb621a267e7f",
5+
"com.unity.multiplayer.tools": "https://github.com/Unity-Technologies/com.unity.multiplayer.tools.git#f935904741c349dc41ba24fda6639041128e8f19",
66
"com.unity.netcode.gameobjects": "file:../../com.unity.netcode.gameobjects",
77
"com.unity.test-framework": "1.1.31",
88
"com.unity.test-framework.performance": "2.8.0-preview",
@@ -41,4 +41,4 @@
4141
"testables": [
4242
"com.unity.netcode.gameobjects"
4343
]
44-
}
44+
}

0 commit comments

Comments
 (0)