* Add more data into the early AcceptConnectionCheck to benefit IP-based connection rejection.
* Add a metric for message resends
* Tune message resends a little more
Action<DataReceivedEventArgs> handler = DataReceived;
if (handler != null)
{
- handler(new DataReceivedEventArgs(msg, sendOption));
+ handler(new DataReceivedEventArgs(this, msg, sendOption));
}
else
{
/// </summary>
long totalBytesReceived;
+ public int MessagesResent { get { return messagesResent; } }
+ int messagesResent;
+
/// <summary>
/// Logs the sending of an unreliable data packet in the statistics.
/// </summary>
Interlocked.Increment(ref helloMessagesReceived);
Interlocked.Add(ref totalBytesReceived, totalLength);
}
+
+ internal void LogMessageResent()
+ {
+ Interlocked.Increment(ref messagesResent);
+ }
}
}
{
public struct DataReceivedEventArgs
{
+ public readonly Connection Sender;
+
/// <summary>
/// The bytes received from the client.
/// </summary>
/// </summary>
public readonly SendOption SendOption;
- public DataReceivedEventArgs(MessageReader msg, SendOption sendOption)
+ public DataReceivedEventArgs(Connection sender, MessageReader msg, SendOption sendOption)
{
+ this.Sender = sender;
this.Message = msg;
this.SendOption = sendOption;
}
public int NumberInUse { get { return this.inuse.Count; } }
public int NumberNotInUse { get { return this.pool.Count; } }
+ public int Size { get { return this.NumberInUse + this.NumberNotInUse; } }
// Available objects
private readonly ConcurrentBag<T> pool = new ConcurrentBag<T>();
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Hazel")]
-[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
private Timer reliablePacketTimer;
+#if DEBUG
+ public event Action<byte[], int> DataSentRaw;
+ public event Action<byte[], int> DataReceivedRaw;
+#endif
+
/// <summary>
/// Creates a new UdpClientConnection.
/// </summary>
/// <inheritdoc />
protected override void WriteBytesToConnection(byte[] bytes, int length)
{
+#if DEBUG
if (TestLagMs > 0)
{
ThreadPool.QueueUserWorkItem(a => { Thread.Sleep(this.TestLagMs); WriteBytesToConnectionReal(bytes, length); });
}
else
+#endif
{
WriteBytesToConnectionReal(bytes, length);
}
}
- public event Action<byte[], int> DataSentRaw;
- public event Action<byte[], int> DataReceivedRaw;
-
private void WriteBytesToConnectionReal(byte[] bytes, int length)
{
+#if DEBUG
DataSentRaw?.Invoke(bytes, length);
+#endif
try
{
/// </summary>
void StartListeningForData()
{
+#if DEBUG
+ if (this.TestLagMs > 0)
+ {
+ Thread.Sleep(this.TestLagMs);
+ }
+#endif
+
var msg = MessageReader.GetSized(ushort.MaxValue);
try
{
return;
}
- if (this.TestLagMs > 0)
- {
- Thread.Sleep(this.TestLagMs);
- }
-
+#if DEBUG
if (this.TestDropRate > 0)
{
if ((this.testDropCount++ % this.TestDropRate) == 0)
}
DataReceivedRaw?.Invoke(msg.Buffer, msg.Length);
+#endif
HandleReceive(msg, msg.Length);
}
return 0;
}
- this.NextTimeout += (int)Math.Min(this.NextTimeout * connection.ResendPingMultiplier, 500);
+ this.NextTimeout += (int)Math.Min(this.NextTimeout * connection.ResendPingMultiplier, 1000);
try
{
connection.WriteBytesToConnection(this.Data, this.Length);
+ connection.Statistics.LogMessageResent();
return 1;
}
catch (InvalidOperationException)
this,
buffer,
sendLength,
- ResendTimeout > 0 ? ResendTimeout : ClampToInt(AveragePingMs * this.ResendPingMultiplier, 300, 1000),
+ ResendTimeout > 0 ? ResendTimeout : (int)Math.Min(AveragePingMs * this.ResendPingMultiplier, 300),
ackCallback);
if (!reliableDataPacketsSent.TryAdd(id, packet))
public int MinConnectionLength = 0;
- public delegate bool AcceptConnectionCheck(byte[] input, out byte[] response);
+ public delegate bool AcceptConnectionCheck(IPEndPoint endPoint, byte[] input, out byte[] response);
public AcceptConnectionCheck AcceptConnection;
/// <summary>
if (AcceptConnection != null)
{
- if (!AcceptConnection(message.Buffer, out var response))
+ if (!AcceptConnection((IPEndPoint)remoteEndPoint, message.Buffer, out var response))
{
message.Recycle();
SendData(response, response.Length, remoteEndPoint);