Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions Hazel.UnitTests/Reliability/PacketDropTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using Hazel.Udp;
using Hazel.Udp.FewerThreads;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Diagnostics;
using System.Net;
using System.Threading;

namespace Hazel.UnitTests.Reliability
{
[TestClass]
public class PacketDropTests
{
// This test fails because even at 10% packet drop and 10ms
[TestMethod]
public void SustainedPacketLossShouldBeFine()
{
var serverEp = new IPEndPoint(IPAddress.Loopback, 23432);
var clientEp = new IPEndPoint(IPAddress.Loopback, 23433);

var logger = new ConsoleLogger(true);

using (SocketCapture capture = new UnreliableSocketCapture(clientEp, serverEp, logger))
using (ThreadLimitedUdpConnectionListener server = new ThreadLimitedUdpConnectionListener(4, serverEp, logger))
using (UnityUdpClientConnection client = new UnityUdpClientConnection(logger, clientEp))
using (Timer timer = new Timer(_ =>
{
var up = Stopwatch.StartNew();
var cnt = client.FixedUpdate();
if (cnt != 0)
{
logger.WriteInfo($"Took {up.ElapsedMilliseconds}ms to resend {cnt} pkts");
}
}, null, 100, 100))
{
server.ReliableResendPollRateMs = 10;
UdpConnection serverClient = null;
server.NewConnection += (evt) => serverClient = (UdpConnection)evt.Connection;

server.Start();
client.Connect();

var msg = MessageWriter.Get(SendOption.Reliable);
msg.Length = 500;
for (int i = 0; i < 100; ++i)
{
client.Send(msg);
// client.FixedUpdate();
Thread.Sleep(1000 / 30);
}

while (serverClient.Statistics.ReliableMessagesReceived < 101)
{
Assert.AreEqual(ConnectionState.Connected, client.State);
// client.FixedUpdate();
Thread.Sleep(1000 / 30);
}

Thread.Sleep(2000);

Assert.AreEqual(serverClient.Statistics.ReliableMessagesReceived, client.Statistics.ReliableMessagesSent);
Assert.IsTrue(6 < client.Statistics.MessagesResent);
Assert.IsTrue(1 > client.AveragePingMs, "Ping was kinda high: " + client.AveragePingMs);

msg.Recycle();
}
}

private class UnreliableSocketCapture : SocketCapture
{
private Random r = new Random(10);

public UnreliableSocketCapture(IPEndPoint captureEndpoint, IPEndPoint remoteEndPoint, ILogger logger = null)
: base(captureEndpoint, remoteEndPoint, logger)
{
}

protected override bool ShouldSendToRemote()
{
// 10% drop rate
return r.NextDouble() > .1f;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
using Hazel.Udp.FewerThreads;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Hazel.UnitTests
namespace Hazel.UnitTests.Reliability
{
[TestClass]
public class StressTests
Expand All @@ -22,13 +22,14 @@ public void StressTestOpeningConnections()
var ep = new IPEndPoint(IPAddress.Loopback, 22023);
Parallel.For(0, 10000,
new ParallelOptions { MaxDegreeOfParallelism = 64 },
(i) => {

var connection = new UdpClientConnection(new TestLogger(), ep);
connection.KeepAliveInterval = 50;
(i) =>
{

var connection = new UdpClientConnection(new TestLogger(), ep);
connection.KeepAliveInterval = 50;

connection.Connect(new byte[5]);
});
connection.Connect(new byte[5]);
});
}

// This was a thing that happened to us a DDoS. Mildly instructional that we straight up ignore it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ private void ReceiveLoop()
}
}

protected virtual bool ShouldSendToRemote() => true;

private void SendToRemoteLoop()
{
while (!this.cancellationToken.IsCancellationRequested)
Expand All @@ -156,8 +158,15 @@ private void SendToRemoteLoop()

if (this.forRemote.TryTake(out var packet))
{
this.logger.WriteInfo($"Passed 1 packet of {packet.Length} bytes to remote");
this.captureSocket.SendTo(packet.GetUnderlyingArray(), packet.Offset, packet.Length, SocketFlags.None, this.remoteEndPoint);
if (ShouldSendToRemote())
{
// this.logger.WriteInfo($"Passed 1 packet of {packet.Length} bytes to remote");
this.captureSocket.SendTo(packet.GetUnderlyingArray(), packet.Offset, packet.Length, SocketFlags.None, this.remoteEndPoint);
}
else
{
this.logger.WriteInfo($"Dropped 1 packet of {packet.Length} bytes to remote");
}
}
}
}
Expand All @@ -176,7 +185,7 @@ private void SendToLocalLoop()

if (this.forLocal.TryTake(out var packet))
{
this.logger.WriteInfo($"Passed 1 packet of {packet.Length} bytes to local");
// this.logger.WriteInfo($"Passed 1 packet of {packet.Length} bytes to local");
this.captureSocket.SendTo(packet.GetUnderlyingArray(), packet.Offset, packet.Length, SocketFlags.None, this.localEndPoint);
}
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading