/// by the end point or because an error occured. If an error occured the error should be passed in in order to
/// pass to the subscribers, otherwise null can be passed in.
/// </remarks>
- protected void InvokeDisconnected(Exception e = null)
+ protected void InvokeDisconnected(string e)
{
//Make a copy to avoid race condition between null check and invocation
EventHandler<DisconnectedEventArgs> handler = Disconnected;
/// that caused it or a <see cref="HazelException"/> with the details of the exception, if the disconnection
/// wasn't caused by an error then this will contain null.
/// </remarks>
- public Exception Exception { get; private set; }
+ public string Reason { get; private set; }
/// <summary>
/// Private constructor for object pool.
/// Sets the given exception for the arguments.
/// </summary>
/// <param name="e">The exception if the cause.</param>
- internal void Set(Exception e)
+ internal void Set(string reason)
{
- this.Exception = e;
+ this.Reason = reason;
}
}
}
}
catch (ObjectDisposedException e)
{
- HandleDisconnect(new HazelException("Could not send as the socket was disposed of.", e));
+ HandleDisconnect("Could not send as the socket was disposed of.");
}
catch (SocketException e)
{
- HandleDisconnect(new HazelException("Could not send data as a SocketException occured.", e));
+ HandleDisconnect("Could not send data as a SocketException occured.");
}
},
null
}
catch (SocketException e)
{
- HazelException he = new HazelException("Could not send data as a SocketException occured.", e);
- HandleDisconnect(he);
- throw he;
- }
- catch (ArgumentOutOfRangeException e)
- {
- HazelException he = new HazelException("Something wonk with the buffer: " + bytes.Length, e);
- HandleDisconnect(he);
+ HandleDisconnect("Could not send data as a SocketException occured.");
+ throw e;
}
}
}
catch (SocketException e)
{
- HandleDisconnect(new HazelException("A socket exception occured while reading data.", e));
+ HandleDisconnect("A socket exception occured while reading data.");
return;
}
//Exit if no bytes read, we've failed.
if (bytesReceived == 0)
{
- HandleDisconnect(new HazelException("Recieved 0 bytes"));
+ HandleDisconnect("Recieved 0 bytes");
return;
}
}
catch (SocketException e)
{
- HandleDisconnect(new HazelException("A Socket exception occured while initiating a receive operation.", e));
+ HandleDisconnect("A Socket exception occured while initiating a receive operation.");
}
catch (ObjectDisposedException)
{
}
/// <inheritdoc />
- protected override void HandleDisconnect(HazelException e = null)
+ protected override void HandleDisconnect(string e)
{
if (State == ConnectionState.Connected)
{
}
int keepAliveInterval = 10000;
+ public int KeepAlivesSent;
+
/// <summary>
/// The timer creating keepalive pulses.
/// </summary>
try
{
ReliableSend((byte)UdpSendOption.Ping);
- Trace.WriteLine("Keepalive packet sent.");
+ Interlocked.Increment(ref KeepAlivesSent);
}
catch
{
/// The packet id that was received last.
/// </summary>
volatile ushort reliableReceiveLast = 0;
-
+
/// <summary>
/// Has the connection received anything yet
/// </summary>
public int LastTimeout;
public volatile bool Acknowledged;
- private Action<Packet> ResendAction;
+ private Func<Packet, int> ResendAction;
public Action AckCallback;
public volatile int Retransmissions;
{
}
- internal void Set(ushort id, byte[] data, Action<Packet> resendAction, int timeout, Action ackCallback)
+ internal void Set(ushort id, byte[] data, Func<Packet, int> resendAction, int timeout, Action ackCallback)
{
this.Id = id;
this.Data = data;
Stopwatch.Restart();
}
- public void Resend()
+ // Packets resent
+ public int Resend()
{
var evt = this.ResendAction;
if (!this.Acknowledged)
{
if (evt != null)
{
- evt(this);
+ return evt(this);
}
}
+
+ return 0;
}
/// <summary>
}
}
- internal void ManageReliablePackets(object state)
+ internal int ManageReliablePackets(object state)
{
+ int output = 0;
if (this.reliableDataPacketsSent.Count > 0)
{
double minTimeout = int.MaxValue;
{
try
{
- pkt.Resend();
+ output += pkt.Resend();
}
catch { }
}
minTimeout = Math.Min(pkt.LastTimeout, minTimeout);
}
}
+
+ return output;
}
/// <summary>
(Packet p) =>
{
// Callback for a previous packet
- if (p.Acknowledged) return;
+ if (p.Acknowledged) return 0;
p.LastSend = DateTime.Now;
{
if (reliableDataPacketsSent.TryRemove(p.Id, out self))
{
- HandleDisconnect(new HazelException($"Reliable packet {self.Id} was not ack'd after {self.Retransmissions} resends"));
+ HandleDisconnect($"Reliable packet {self.Id} was not ack'd after {self.Retransmissions} resends");
self.Recycle();
}
- return;
+ return 0;
}
// Backoff retry frequency to avoid congestion
{
WriteBytesToConnection(p.Data, sendLength);
p.Retransmissions++;
+ return 1;
}
- catch (InvalidOperationException e)
+ catch (InvalidOperationException)
{
//No longer connected
- HandleDisconnect(new HazelException("Could not resend data as connection is no longer connected", e));
+ HandleDisconnect("Could not resend data as connection is no longer connected");
}
- Trace.WriteLine("Resend.");
+ return 0;
},
timeout,
ackCallback
break;
case (byte)UdpSendOption.Disconnect:
- HandleDisconnect(new HazelException("The remote sent a disconnect request"));
+ HandleDisconnect("The remote sent a disconnect request");
message.Recycle();
break;
/// Called when the socket has been disconnected at the remote host.
/// </summary>
/// <param name="e">The exception if one was the cause.</param>
- protected abstract void HandleDisconnect(HazelException e = null);
+ protected abstract void HandleDisconnect(string reason);
/// <summary>
/// Sends a disconnect message to the end point.
}
public float AveragePacketsTime = 1;
+ public int PacketsResent = 0;
+
Stopwatch stopwatch = new Stopwatch();
private void ManageReliablePackets(object state)
{
stopwatch.Restart();
foreach (var kvp in this.allConnections)
{
- kvp.Value.ManageReliablePackets(state);
+ PacketsResent += kvp.Value.ManageReliablePackets(state);
}
this.AveragePacketsTime = this.AveragePacketsTime * .7f + stopwatch.ElapsedMilliseconds * .3f;
}
/// <inheritdoc />
- protected override void HandleDisconnect(HazelException e = null)
+ protected override void HandleDisconnect(string reason)
{
bool invoke = false;
{
try
{
- InvokeDisconnected(e);
+ InvokeDisconnected(reason);
}
catch { }