public int TestLagMs = -1;
- public event Action<byte[], int> DataSentRaw;
- protected void InvokeDataSentRaw(byte[] data, int length)
- {
- this.DataSentRaw?.Invoke(data, length);
- }
-
- public event Action<byte[]> DataReceivedRaw;
- protected void InvokeDataReceivedRaw(byte[] data)
- {
- this.DataReceivedRaw?.Invoke(data);
- }
-
/// <summary>
/// Called when the end point disconnects or an error occurs.
/// </summary>
if (disposing)
{
this.DataReceived = null;
- this.DataReceivedRaw = null;
- this.DataSentRaw = null;
this.Disconnected = null;
}
}
}
}
+
+ public event Action<byte[], int> DataSentRaw;
+ public event Action<byte[]> DataReceivedRaw;
+
private void WriteBytesToConnectionReal(byte[] bytes, int length)
{
- InvokeDataSentRaw(bytes, length);
+ DataSentRaw?.Invoke(bytes, length);
if (State != ConnectionState.Connected && State != ConnectionState.Connecting)
throw new InvalidOperationException("Could not send data as this Connection is not connected and is not connecting. Did you disconnect?");
protected override void WriteBytesToConnectionSync(byte[] bytes, int length)
{
- InvokeDataSentRaw(bytes, length);
+ DataSentRaw?.Invoke(bytes, length);
if (State != ConnectionState.Connected && State != ConnectionState.Connecting)
throw new InvalidOperationException("Could not send data as this Connection is not connected and is not connecting. Did you disconnect?");
Thread.Sleep(this.TestLagMs);
}
+ DataReceivedRaw?.Invoke(bytes);
MessageReader msg = MessageReader.GetRaw(bytes, 0, bytesReceived);
HandleReceive(msg, bytesReceived);
}
+ /// <summary>
+ /// Sends a disconnect message to the end point.
+ /// </summary>
+ protected override void SendDisconnect()
+ {
+ try
+ {
+ WriteBytesToConnectionSync(DisconnectBytes, 1);
+ }
+ catch { }
+ }
+
/// <inheritdoc />
protected override void Dispose(bool disposing)
{
/// <inheritdoc />
public abstract partial class UdpConnection : NetworkConnection
{
+ protected static readonly byte[] DisconnectBytes = new byte[] { (byte)UdpSendOption.Disconnect };
+
/// <summary>
/// Creates a new UdpConnection and initializes the keep alive timer.
/// </summary>
/// <param name="message">The buffer containing the bytes received.</param>
protected internal void HandleReceive(MessageReader message, int bytesReceived)
{
- InvokeDataReceivedRaw(message.Buffer);
-
ushort id;
switch (message.Buffer[0])
{
break;
case (byte)UdpSendOption.Disconnect:
- Disconnect("The remote sent a disconnect request");
+ Disconnect("The remote sent a disconnect request", true);
message.Recycle();
break;
/// </summary>
/// <param name="e">The exception if one was the cause.</param>
public override void Disconnect(string reason)
+ {
+ this.Disconnect(reason, false);
+ }
+
+ protected void Disconnect(string reason, bool skipSendDisconnect)
{
bool invoke = false;
lock (this)
{
if (this.state == ConnectionState.Connected)
{
- this.state = ConnectionState.Disconnecting;
+ this.state = skipSendDisconnect ? ConnectionState.NotConnected : ConnectionState.Disconnecting;
invoke = true;
}
}
this.Dispose();
}
-
- /// <summary>
- /// Sends a disconnect message to the end point.
- /// </summary>
- protected override void SendDisconnect()
- {
- try
- {
- WriteBytesToConnectionSync(new byte[] { (byte)UdpSendOption.Disconnect }, 1);
- }
- catch { }
- }
-
+
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
/// <param name="result">The asyncronous operation's result.</param>
public int ActiveListeners;
+ public int PacketsReceived;
void ReadCallback(IAsyncResult result)
{
Interlocked.Decrement(ref ActiveListeners);
+ Interlocked.Increment(ref PacketsReceived);
var message = (MessageReader)result.AsyncState;
int bytesReceived;
return;
}
- // Exit if no bytes read, we've closed.
+ // I'm a little concerned about a infinite loop here, but it seems like it's possible
+ // to get 0 bytes read on UDP without the socket being shut down.
if (bytesReceived == 0)
{
message.Recycle();
- this.Logger?.Invoke("Stopped due to receiving 0 bytes");
+ StartListeningForData();
return;
}
/// <inheritdoc />
protected override void WriteBytesToConnection(byte[] bytes, int length)
{
- InvokeDataSentRaw(bytes, length);
-
if (State != ConnectionState.Connected)
throw new InvalidOperationException("Could not send data: Not connected.");
/// <inheritdoc />
protected override void WriteBytesToConnectionSync(byte[] bytes, int length)
{
- InvokeDataSentRaw(bytes, length);
-
// No throw: As an internal interface, I want to try sending bytes whenever the I feel like it.
Listener.SendDataSync(bytes, length, RemoteEndPoint);
{
throw new HazelException("Cannot manually connect a UdpServerConnection, did you mean to use UdpClientConnection?");
}
-
+
+
+ /// <summary>
+ /// Sends a disconnect message to the end point.
+ /// </summary>
+ protected override void SendDisconnect()
+ {
+ try
+ {
+ WriteBytesToConnection(DisconnectBytes, 1);
+ }
+ catch { }
+ }
+
protected override void Dispose(bool disposing)
{
Listener.RemoveConnectionTo(RemoteEndPoint);
}
}
+
base.Dispose(disposing);
}
}