From 64dbd02874577453d0d2d27017f2027dea49b007 Mon Sep 17 00:00:00 2001 From: "derek.holloway" Date: Thu, 2 Jul 2026 16:36:23 -0700 Subject: [PATCH] Rework the server connection to be more structured --- MistoxServer/Interface/Interface.cs | 23 ++------ MistoxServer/Interface/ServerInterface.cs | 70 ++++++++++------------- MistoxServer/Server/Connection.cs | 10 ---- MistoxServer/Server/ServerListener.cs | 38 ++++++------ MistoxServer/Server/TCPConnection.cs | 54 +++++++++++++++++ MistoxServer/Server/TCPServer.cs | 47 --------------- MistoxServer/Server/serverConnection.cs | 30 ++++++++++ MistoxServer/mExtensions.cs | 2 +- MistoxServer/mPacket/DataPacket.cs | 4 +- MistoxServer/mPacket/PacketAttribute.cs | 2 +- 10 files changed, 139 insertions(+), 141 deletions(-) delete mode 100644 MistoxServer/Server/Connection.cs create mode 100644 MistoxServer/Server/TCPConnection.cs delete mode 100644 MistoxServer/Server/TCPServer.cs create mode 100644 MistoxServer/Server/serverConnection.cs diff --git a/MistoxServer/Interface/Interface.cs b/MistoxServer/Interface/Interface.cs index e5f6c9f..061a291 100644 --- a/MistoxServer/Interface/Interface.cs +++ b/MistoxServer/Interface/Interface.cs @@ -1,16 +1,15 @@ using System; using System.Net; -using System.Threading.Tasks; -namespace MistoxServer { +namespace Mistox { public class mServer { - public static IMistoxServer newServer(int port) { + public static ServerInterface newServer(int port, string serverName) { DataPacket.BuildNetworkPacketList(); - return new ServerInterface(port); + return new ServerInterface(port, serverName); } - public static IMistoxServer newClient(string ServerIPOrHostName, int Port) { + public static ClientInterface newClient(string ServerIPOrHostName, int Port) { DataPacket.BuildNetworkPacketList(); int index = 0; IPAddress[] remoteAddress = Dns.GetHostAddresses(ServerIPOrHostName); @@ -30,18 +29,4 @@ namespace MistoxServer { } - public interface IMistoxServer { - public event EventHandler onConnected; - public event EventHandler onSlowReceive; - public event EventHandler onFastReceive; - public event EventHandler onDisconnected; - - public Task Send(Packet data, SendType speed); - } - - public enum SendType { - SlowUpdate, - FastUpdate - } - } diff --git a/MistoxServer/Interface/ServerInterface.cs b/MistoxServer/Interface/ServerInterface.cs index 67fabcb..c8518e1 100644 --- a/MistoxServer/Interface/ServerInterface.cs +++ b/MistoxServer/Interface/ServerInterface.cs @@ -1,59 +1,47 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Net; using System.Threading.Tasks; -using MistoxServer.Client; -using MistoxServer.Server; +using Mistox.Server; -namespace MistoxServer { - public class ServerInterface : IMistoxServer { +namespace Mistox { + public class ServerInterface { - mUDPClient FastUpdateServer; - mTCPListener SlowUpdateServer; - List Connections = new List(); + MistoxServer ServerInstance; - public event EventHandler onConnected; - public event EventHandler onSlowReceive; - public event EventHandler onFastReceive; - public event EventHandler onDisconnected; + public event EventHandler onUserConnected; + public event EventHandler onReceive; + public event EventHandler onUserDisconnected; - public ServerInterface( int port ) { + public ServerInterface( int port, string serverName ) { - // Initilize the server listening connections - SlowUpdateServer = new mTCPListener( port ); - SlowUpdateServer.onConnected += OnConnected; - SlowUpdateServer.onDisconnected += OnDisconnected; + // Initilize the server + ServerInstance = new MistoxServer() { + ServerName = serverName, + BindAddress = IPAddress.Any, + Port = port, + MaxClients = 10, + Connections = new ConcurrentDictionary() + }; - FastUpdateServer = new mUDPClient( new IPEndPoint( IPAddress.Any, port ) ); - FastUpdateServer.onReceived += ( object o, EventArgs e ) => { onFastReceive?.Invoke( o, e ); }; + // Start listening for connections and wire up the server + ServerInstance.serverListener = new ServerListener( ServerInstance ); + ServerInstance.serverListener.onConnected += onUserConnected; + ServerInstance.serverListener.onReceive += onReceive; + ServerInstance.serverListener.onDisconnected += onUserDisconnected; Console.WriteLine( "The Server is initilized and waiting for clients to connect at port : " + port ); } - void OnConnected( object sender, EventArgs e ) { - Connection user = (Connection)sender; - onConnected?.Invoke( sender, e ); - user.slowClient.onReceived += ( object o, EventArgs e ) => { onSlowReceive?.Invoke( o, e ); }; - user.slowClient.onDisconnected += OnDisconnected; - Connections.Add( user ); - } - - void OnDisconnected( object sender, EventArgs e ) { - Connection user = (Connection)sender; - onDisconnected?.Invoke( sender, e ); - Connections.Remove( user ); - } - - public async Task Send( Packet data, SendType speed ) { - if (speed == SendType.SlowUpdate) { - foreach( Connection cur in Connections ) { - await cur.slowClient.Send( data ); - } - } else { - foreach( Connection cur in Connections ) { - await FastUpdateServer.Send( data, cur.fastClient ); - } + public async Task SendAllClients(Packet data) { + foreach( KeyValuePair cur in ServerInstance.Connections ) { + await cur.Value.Connection.Send(data); } } + + public async Task SendClient(string UserName, Packet data) { + await ServerInstance.Connections[UserName].Connection.Send( data ); + } } } diff --git a/MistoxServer/Server/Connection.cs b/MistoxServer/Server/Connection.cs deleted file mode 100644 index 9b4dedc..0000000 --- a/MistoxServer/Server/Connection.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Net; - -namespace MistoxServer.Server { - - public class Connection { - public mTCPServer slowClient { get; set; } - public IPEndPoint fastClient { get; set; } - } - -} diff --git a/MistoxServer/Server/ServerListener.cs b/MistoxServer/Server/ServerListener.cs index 9fdba59..636ca0e 100644 --- a/MistoxServer/Server/ServerListener.cs +++ b/MistoxServer/Server/ServerListener.cs @@ -6,48 +6,46 @@ using System.Threading.Tasks; // Client Connections -namespace MistoxServer.Server { - public class mTCPListener : IDisposable { +namespace Mistox.Server { + public class ServerListener : IDisposable { public event EventHandler onConnected; public event EventHandler onDisconnected; public event EventHandler onReceive; + MistoxServer _MistoxServer; TcpListener Listener; - bool Alive; - int port; - public mTCPListener( int Port ) { - port = Port; - Alive = true; + public ServerListener( MistoxServer ServerInstance ) { + _MistoxServer = ServerInstance; Thread ConnectionThread = new Thread(async () => await ListenerThread() ); ConnectionThread.Start(); } async Task ListenerThread() { - Listener = new TcpListener( IPAddress.Any, port ); + Listener = new TcpListener( _MistoxServer.BindAddress, _MistoxServer.Port ); Listener.Start(); - while( Alive ) { + while( _MistoxServer.Alive ) { TcpClient client = await Listener.AcceptTcpClientAsync(); + + if (_MistoxServer.Connections.Count + 1 > _MistoxServer.MaxClients) { + continue; + } - Connection user = new Connection(){ - slowClient = new mTCPServer( client ), - fastClient = new IPEndPoint( ((IPEndPoint)client.Client.RemoteEndPoint).Address, port ) + IPEndPoint remote = client.Client.RemoteEndPoint as IPEndPoint; + string connectionID = Guid.NewGuid().ToString(); + + _MistoxServer.Connections[connectionID] = new TcpClientConnection() { + Connection = new TCPConnection( client, _MistoxServer, connectionID ), + RemoteAddress = remote.Address }; Console.WriteLine( "New User Connected" ); - - onConnected?.Invoke( user, new EventArgs() ); - user.slowClient.onDisconnected += onDisconnected; - user.slowClient.onReceived += onReceive; - - Thread receiveThread = new Thread(async () => await user.slowClient.ReceiveThread(user) ); - receiveThread.Start(); + onConnected?.Invoke( _MistoxServer.Connections[connectionID], new EventArgs() ); } } public void Dispose() { - Alive = false; Listener.Stop(); Listener = null; } diff --git a/MistoxServer/Server/TCPConnection.cs b/MistoxServer/Server/TCPConnection.cs new file mode 100644 index 0000000..8fd6ae0 --- /dev/null +++ b/MistoxServer/Server/TCPConnection.cs @@ -0,0 +1,54 @@ +using System; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; + +namespace Mistox.Server { + public class TCPConnection : IDisposable { + + TcpClient _client; + MistoxServer _instance; + string _connectionID; + + public TCPConnection( TcpClient tcpClient, MistoxServer ServerInstance, string ConnectionID ) { + _client = tcpClient; + _instance = ServerInstance; + _connectionID = ConnectionID; + _client.NoDelay = true; + + // Start the receive thread + Thread receiveThread = new Thread(async () => await ReceiveThread() ); + receiveThread.Start(); + } + + public async Task ReceiveThread() { + while( _client.Connected && _instance.Connections[_connectionID].Connected ) { + try { + _instance.Connections[_connectionID].LastHeartbeat = DateTime.UtcNow; + byte[] StreamData = new byte[1024]; + int bytesRead = await _client.GetStream().ReadAsync(StreamData, 0, StreamData.Length); + if( bytesRead > 0 ) { + dynamic data = mSerialize.tReceive( StreamData.Sub( 0, bytesRead ) ); + if( data != null ) { + _instance.onReceived?.Invoke( data, new EventArgs() ); + } + } + } catch( Exception ) { + Console.WriteLine( "User disconnected" ); + Dispose(); + } + } + } + + public async Task Send( T packet ) { + byte[] byteData = DataPacket.Serialize( packet ); + await _client.GetStream().WriteAsync( byteData, 0, byteData.Length ); + } + + public void Dispose() { + _instance.Connections[_connectionID].Connected = false; + _instance.onUserDisconnected?.Invoke( _instance.Connections[_connectionID], new EventArgs() ); + _instance.Connections.TryRemove( _connectionID, out _ ); + } + } +} diff --git a/MistoxServer/Server/TCPServer.cs b/MistoxServer/Server/TCPServer.cs deleted file mode 100644 index 4df6784..0000000 --- a/MistoxServer/Server/TCPServer.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Net.Sockets; -using System.Threading.Tasks; - -namespace MistoxServer.Server { - public class mTCPServer : IDisposable { - public TcpClient slowClient; - - public event EventHandler onReceived; - public event EventHandler onDisconnected; - - public mTCPServer( TcpClient client ) { - slowClient = client; - slowClient.Client.NoDelay = true; - } - - bool Alive = true; - public async Task ReceiveThread( Connection Client ) { - bool connected = true; - while( Alive && connected ) { - try { - byte[] StreamData = new byte[1024]; - int bytesRead = await slowClient.GetStream().ReadAsync(StreamData, 0, StreamData.Length); - if( bytesRead > 0 ) { - dynamic data = mSerialize.tReceive( StreamData.Sub( 0, bytesRead ) ); - if( data != null ) { - onReceived?.Invoke( data, new EventArgs() ); - } - } - } catch( Exception ) { - Console.WriteLine( "User disconnected" ); - connected = false; - onDisconnected?.Invoke( Client, new EventArgs() ); - } - } - } - - public async Task Send( T packet ) { - byte[] byteData = DataPacket.Serialize( packet ); - await slowClient.GetStream().WriteAsync( byteData, 0, byteData.Length ); - } - - public void Dispose() { - Alive = false; - } - } -} diff --git a/MistoxServer/Server/serverConnection.cs b/MistoxServer/Server/serverConnection.cs new file mode 100644 index 0000000..23c1ba6 --- /dev/null +++ b/MistoxServer/Server/serverConnection.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Concurrent; +using System.Net; + +namespace Mistox.Server { + + public class MistoxServer { + public string ServerName { get; set; } = ""; + public IPAddress BindAddress { get; set; } = IPAddress.Any; + public int Port { get; set; } = 9126; + public int MaxClients { get; set; } = 10; + public bool Alive { get; set; } = true; + public ServerListener serverListener; + public ConcurrentDictionary Connections { get; set; } + + public EventHandler onUserConnected; + public EventHandler onReceived; + public EventHandler onUserDisconnected; + } + + public class TcpClientConnection { + public string UserName { get; set; } = ""; + public bool IsAuthenticated { get; set; } = false; + public DateTime LastHeartbeat { get; set; } = DateTime.UtcNow; + public bool Connected { get; set; } = true; + public IPAddress RemoteAddress { get; set; } + public TCPConnection Connection { get; set; } + } + +} diff --git a/MistoxServer/mExtensions.cs b/MistoxServer/mExtensions.cs index d0b02ff..b77266b 100644 --- a/MistoxServer/mExtensions.cs +++ b/MistoxServer/mExtensions.cs @@ -1,6 +1,6 @@ using System; -namespace MistoxServer { +namespace Mistox { static class Extensions { public static T[] Join( this T[] first, T[] second ) { diff --git a/MistoxServer/mPacket/DataPacket.cs b/MistoxServer/mPacket/DataPacket.cs index 05b0b70..e116e2e 100644 --- a/MistoxServer/mPacket/DataPacket.cs +++ b/MistoxServer/mPacket/DataPacket.cs @@ -2,10 +2,10 @@ using System; using System.Collections.Generic; using System.IO; using System.Reflection; -using MistoxServer.Attributes; +using Mistox.Attributes; using MsgPack.Serialization; -namespace MistoxServer { +namespace Mistox { public class DataPacket { // The length of the packet header in bytes diff --git a/MistoxServer/mPacket/PacketAttribute.cs b/MistoxServer/mPacket/PacketAttribute.cs index 298b4e1..bbd6874 100644 --- a/MistoxServer/mPacket/PacketAttribute.cs +++ b/MistoxServer/mPacket/PacketAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace MistoxServer.Attributes { +namespace Mistox.Attributes { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] public sealed class mPacket : Attribute {