Rework the server connection to be more structured

This commit is contained in:
derek.holloway committed 2026-07-02 16:36:23 -07:00
1 parent 7b58ca0338
commit 64dbd02874
10 files changed
+139 -141

No files matched your search

+4 -19
View File
@@ -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>(Packet data, SendType speed);
}
public enum SendType {
SlowUpdate,
FastUpdate
}
}
+29 -41
View File
@@ -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<Connection> Connections = new List<Connection>();
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<string, TcpClientConnection>()
};
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>( 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>(Packet data) {
foreach( KeyValuePair<string, TcpClientConnection> cur in ServerInstance.Connections ) {
await cur.Value.Connection.Send(data);
}
}
public async Task SendClient<Packet>(string UserName, Packet data) {
await ServerInstance.Connections[UserName].Connection.Send( data );
}
}
}
-10
View File
@@ -1,10 +0,0 @@
using System.Net;
namespace MistoxServer.Server {
public class Connection {
public mTCPServer slowClient { get; set; }
public IPEndPoint fastClient { get; set; }
}
}
+18 -20
View File
@@ -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();
Connection user = new Connection(){
slowClient = new mTCPServer( client ),
fastClient = new IPEndPoint( ((IPEndPoint)client.Client.RemoteEndPoint).Address, port )
if (_MistoxServer.Connections.Count + 1 > _MistoxServer.MaxClients) {
continue;
}
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;
}
+54
View File
@@ -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>( 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 _ );
}
}
}
-47
View File
@@ -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>( T packet ) {
byte[] byteData = DataPacket.Serialize( packet );
await slowClient.GetStream().WriteAsync( byteData, 0, byteData.Length );
}
public void Dispose() {
Alive = false;
}
}
}
+30
View File
@@ -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<string, TcpClientConnection> 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; }
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
using System;
namespace MistoxServer {
namespace Mistox {
static class Extensions {
public static T[] Join<T>( this T[] first, T[] second ) {
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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 {