From 8d2a2cd5de40e2b94ef5007c32832ed9a063dc40 Mon Sep 17 00:00:00 2001 From: chai <215380520@qq.com> Date: Thu, 12 Oct 2023 22:09:49 +0800 Subject: +hazel-networking --- Tools/Hazel-Networking/Hazel/Connection.cs | 234 +++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 Tools/Hazel-Networking/Hazel/Connection.cs (limited to 'Tools/Hazel-Networking/Hazel/Connection.cs') diff --git a/Tools/Hazel-Networking/Hazel/Connection.cs b/Tools/Hazel-Networking/Hazel/Connection.cs new file mode 100644 index 0000000..da2f59a --- /dev/null +++ b/Tools/Hazel-Networking/Hazel/Connection.cs @@ -0,0 +1,234 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Net.Sockets; +using System.Net; +using System.Threading; + +namespace Hazel +{ + /// + /// Base class for all connections. + /// + /// + /// + /// Connection is the base class for all connections that Hazel can make. It provides common functionality and a + /// standard interface to allow connections to be swapped easily. + /// + /// + /// Any class inheriting from Connection should provide the 3 standard guarantees that Hazel provides: + /// + /// + /// Thread Safe + /// + /// + /// Connection Orientated + /// + /// + /// Packet/Message Based + /// + /// + /// + /// + /// + public abstract class Connection : IDisposable + { + /// + /// Called when a message has been received. + /// + /// + /// + /// DataReceived is invoked everytime a message is received from the end point of this connection, the message + /// that was received can be found in the alongside other information from the + /// event. + /// + /// + /// + /// + /// + /// + public event Action DataReceived; + + public int TestLagMs = -1; + public int TestDropRate = 0; + protected int testDropCount = 0; + + /// + /// Called when the end point disconnects or an error occurs. + /// + /// + /// + /// Disconnected is invoked when the connection is closed due to an exception occuring or because the remote + /// end point disconnected. If it was invoked due to an exception occuring then the exception is available + /// in the passed with the event. + /// + /// + /// + /// + /// + /// + public event EventHandler Disconnected; + + /// + /// The remote end point of this Connection. + /// + /// + /// This is the end point that this connection is connected to (i.e. the other device). This returns an abstract + /// which can then be cast to an appropriate end point depending on the + /// connection type. + /// + public IPEndPoint EndPoint { get; protected set; } + + public IPMode IPMode { get; protected set; } + + /// + /// The traffic statistics about this Connection. + /// + /// + /// Contains statistics about the number of messages and bytes sent and received by this connection. + /// + public ConnectionStatistics Statistics { get; protected set; } + + /// + /// The state of this connection. + /// + /// + /// All implementers should be aware that when this is set to ConnectionState.Connected it will + /// release all threads that are blocked on . + /// + public ConnectionState State + { + get + { + return this._state; + } + + protected set + { + this._state = value; + this.SetState(value); + } + } + + protected ConnectionState _state; + protected virtual void SetState(ConnectionState state) { } + + /// + /// Constructor that initializes the ConnecitonStatistics object. + /// + /// + /// This constructor initialises with empty statistics and sets to + /// . + /// + protected Connection() + { + this.Statistics = new ConnectionStatistics(); + this.State = ConnectionState.NotConnected; + } + + /// + /// Sends a number of bytes to the end point of the connection using the specified . + /// + /// The message to send. + public abstract SendErrors Send(MessageWriter msg); + + /// + /// Connects the connection to a server and begins listening. + /// This method blocks and may thrown if there is a problem connecting. + /// + /// The bytes of data to send in the handshake. + /// The number of milliseconds to wait before giving up on the connect attempt. + public abstract void Connect(byte[] bytes = null, int timeout = 5000); + + /// + /// Connects the connection to a server and begins listening. + /// This method does not block. + /// + /// The bytes of data to send in the handshake. + public abstract void ConnectAsync(byte[] bytes = null); + + /// + /// Invokes the DataReceived event. + /// + /// The bytes received. + /// The the message was received with. + /// + /// Invokes the event on this connection to alert subscribers a new message has been + /// received. The bytes and the send option that the message was sent with should be passed in to give to the + /// subscribers. + /// + protected void InvokeDataReceived(MessageReader msg, SendOption sendOption) + { + // Make a copy to avoid race condition between null check and invocation + Action handler = DataReceived; + if (handler != null) + { + try + { + handler(new DataReceivedEventArgs(this, msg, sendOption)); + } + catch { } + } + else + { + msg.Recycle(); + } + } + + /// + /// Invokes the Disconnected event. + /// + /// The exception, if any, that occurred to cause this. + /// Extra disconnect data + /// + /// Invokes the event to alert subscribres this connection has been disconnected either + /// by the end point or because an error occurred. If an error occurred the error should be passed in in order to + /// pass to the subscribers, otherwise null can be passed in. + /// + protected void InvokeDisconnected(string e, MessageReader reader) + { + // Make a copy to avoid race condition between null check and invocation + EventHandler handler = Disconnected; + if (handler != null) + { + DisconnectedEventArgs args = new DisconnectedEventArgs(e, reader); + try + { + handler(this, args); + } + catch + { + } + } + } + + /// + /// For times when you want to force the disconnect handler to fire as well as close it. + /// If you only want to close it, just use Dispose. + /// + public abstract void Disconnect(string reason, MessageWriter writer = null); + + /// + /// Disposes of this NetworkConnection. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Disposes of this NetworkConnection. + /// + /// Are we currently disposing? + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + this.DataReceived = null; + this.Disconnected = null; + } + } + } +} -- cgit v1.1-26-g67d0