aboutsummaryrefslogtreecommitdiff
path: root/Tools/Hazel-Networking/Hazel/NetworkConnection.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/Hazel-Networking/Hazel/NetworkConnection.cs')
-rw-r--r--Tools/Hazel-Networking/Hazel/NetworkConnection.cs117
1 files changed, 117 insertions, 0 deletions
diff --git a/Tools/Hazel-Networking/Hazel/NetworkConnection.cs b/Tools/Hazel-Networking/Hazel/NetworkConnection.cs
new file mode 100644
index 0000000..d1de8a8
--- /dev/null
+++ b/Tools/Hazel-Networking/Hazel/NetworkConnection.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+
+
+namespace Hazel
+{
+ public enum HazelInternalErrors
+ {
+ SocketExceptionSend,
+ SocketExceptionReceive,
+ ReceivedZeroBytes,
+ PingsWithoutResponse,
+ ReliablePacketWithoutResponse,
+ ConnectionDisconnected,
+ DtlsNegotiationFailed
+ }
+
+ /// <summary>
+ /// Abstract base class for a <see cref="Connection"/> to a remote end point via a network protocol like TCP or UDP.
+ /// </summary>
+ /// <threadsafety static="true" instance="true"/>
+ public abstract class NetworkConnection : Connection
+ {
+ /// <summary>
+ /// An event that gives us a chance to send well-formed disconnect messages to clients when an internal disconnect happens.
+ /// </summary>
+ public Func<HazelInternalErrors, MessageWriter> OnInternalDisconnect;
+
+ public virtual float AveragePingMs { get; }
+
+ public long GetIP4Address()
+ {
+ if (IPMode == IPMode.IPv4)
+ {
+ return this.EndPoint.Address.Address;
+ }
+ else
+ {
+ var bytes = this.EndPoint.Address.GetAddressBytes();
+ return BitConverter.ToInt64(bytes, bytes.Length - 8);
+ }
+ }
+
+ /// <summary>
+ /// Sends a disconnect message to the end point.
+ /// </summary>
+ protected abstract bool SendDisconnect(MessageWriter writer);
+
+ /// <summary>
+ /// Called when the socket has been disconnected at the remote host.
+ /// </summary>
+ protected void DisconnectRemote(string reason, MessageReader reader)
+ {
+ if (this.SendDisconnect(null))
+ {
+ try
+ {
+ InvokeDisconnected(reason, reader);
+ }
+ catch { }
+ }
+
+ this.Dispose();
+ }
+
+ /// <summary>
+ /// Called when socket is disconnected internally
+ /// </summary>
+ internal void DisconnectInternal(HazelInternalErrors error, string reason)
+ {
+ var handler = this.OnInternalDisconnect;
+ if (handler != null)
+ {
+ MessageWriter messageToRemote = handler(error);
+ if (messageToRemote != null)
+ {
+ try
+ {
+ Disconnect(reason, messageToRemote);
+ }
+ finally
+ {
+ messageToRemote.Recycle();
+ }
+ }
+ else
+ {
+ Disconnect(reason);
+ }
+ }
+ else
+ {
+ Disconnect(reason);
+ }
+ }
+
+ /// <summary>
+ /// Called when the socket has been disconnected locally.
+ /// </summary>
+ public override void Disconnect(string reason, MessageWriter writer = null)
+ {
+ if (this.SendDisconnect(writer))
+ {
+ try
+ {
+ InvokeDisconnected(reason, null);
+ }
+ catch { }
+ }
+
+ this.Dispose();
+ }
+ }
+}