From a12a3949bf45bb022e77a5c0217c9d2c866512e7 Mon Sep 17 00:00:00 2001 From: SHM Date: Mon, 21 Apr 2025 08:30:59 +0900 Subject: [PATCH] =?UTF-8?q?[=EC=84=B1=ED=98=84=EB=AA=A8]=20Http,=20Socket?= =?UTF-8?q?=20=ED=86=B5=EC=8B=A0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Projects/DLL/SystemX.Core.dll | Bin 12800 -> 30720 bytes .../DBPatch/sqlScripts/dacpac/HubX.DB.dacpac | Bin 3047 -> 3046 bytes .../HubX/HubX.Library/HubX.Library.csproj | 10 + .../HubX/HubX.Library/Socket/Object/Client.cs | 29 ++ .../Socket/Object/EnumObjectType.cs | 14 + .../Socket/Object/ObjectManager.cs | 80 +++ .../Socket/Packet/EnumMessageId.cs | 33 ++ .../Socket/Packet/PacketHandler.cs | 43 ++ .../HubX.Library/Socket/Packet/Protocol.cs | 46 ++ .../Socket/Packet/ServerPacketManager.cs | 72 +++ .../Socket/Session/ClientSession.cs | 56 +++ .../Socket/Session/SessionManager.cs | 54 +++ Projects/HubX/HubX.Server/HubX.Server.csproj | 12 + Projects/HubX/HubX.Server/Program.cs | 29 +- .../Properties/launchSettings.json | 61 ++- .../SystemX.Core/Communication/Http.cs | 112 +++++ .../Communication/Socket/Listener.cs | 60 +++ .../Communication/Socket/RecvBuffer.cs | 69 +++ .../Communication/Socket/Session.cs | 239 +++++++++ .../SystemX.Core/SystemX.Core/DB/DataBase.cs | 33 ++ .../SystemX.Core/SystemX.Core/DB/EFCore.cs | 106 ++++ .../SystemX.Core/Log4net/Log4net.cs | 459 +++++++++--------- .../SystemX.Core/SystemX.Core.csproj | 1 + .../SystemX.Core/Utils/DateTimeUtils.cs | 15 + .../SystemX.Core/{Json => Utils}/JsonUtils.cs | 1 - 25 files changed, 1370 insertions(+), 264 deletions(-) create mode 100644 Projects/HubX/HubX.Library/Socket/Object/Client.cs create mode 100644 Projects/HubX/HubX.Library/Socket/Object/EnumObjectType.cs create mode 100644 Projects/HubX/HubX.Library/Socket/Object/ObjectManager.cs create mode 100644 Projects/HubX/HubX.Library/Socket/Packet/EnumMessageId.cs create mode 100644 Projects/HubX/HubX.Library/Socket/Packet/PacketHandler.cs create mode 100644 Projects/HubX/HubX.Library/Socket/Packet/Protocol.cs create mode 100644 Projects/HubX/HubX.Library/Socket/Packet/ServerPacketManager.cs create mode 100644 Projects/HubX/HubX.Library/Socket/Session/ClientSession.cs create mode 100644 Projects/HubX/HubX.Library/Socket/Session/SessionManager.cs create mode 100644 Projects/SystemX.Core/SystemX.Core/Communication/Http.cs create mode 100644 Projects/SystemX.Core/SystemX.Core/Communication/Socket/Listener.cs create mode 100644 Projects/SystemX.Core/SystemX.Core/Communication/Socket/RecvBuffer.cs create mode 100644 Projects/SystemX.Core/SystemX.Core/Communication/Socket/Session.cs create mode 100644 Projects/SystemX.Core/SystemX.Core/DB/DataBase.cs create mode 100644 Projects/SystemX.Core/SystemX.Core/DB/EFCore.cs create mode 100644 Projects/SystemX.Core/SystemX.Core/Utils/DateTimeUtils.cs rename Projects/SystemX.Core/SystemX.Core/{Json => Utils}/JsonUtils.cs (97%) diff --git a/Projects/DLL/SystemX.Core.dll b/Projects/DLL/SystemX.Core.dll index 135cf625acb7040865abc4b5de0b9c82c9aa3be8..7515f20994d1af6b03382097d447394dd0399113 100644 GIT binary patch literal 30720 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 delta 4231 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 + + + + + + + ..\..\DLL\SystemX.Core.dll + + + diff --git a/Projects/HubX/HubX.Library/Socket/Object/Client.cs b/Projects/HubX/HubX.Library/Socket/Object/Client.cs new file mode 100644 index 0000000..f2f957a --- /dev/null +++ b/Projects/HubX/HubX.Library/Socket/Object/Client.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HubX.Library.Socket.Session; + +namespace HubX.Library.Socket.Object +{ + public class Client + { + + public EnumObjectType ObjectType = EnumObjectType.Client; + + private int ClientId; + public int Id + { + get { return ClientId; } + set { ClientId = value; } + } + + public ClientSession Session { get; set; } + + public Client() + { + + } + } +} diff --git a/Projects/HubX/HubX.Library/Socket/Object/EnumObjectType.cs b/Projects/HubX/HubX.Library/Socket/Object/EnumObjectType.cs new file mode 100644 index 0000000..84888f3 --- /dev/null +++ b/Projects/HubX/HubX.Library/Socket/Object/EnumObjectType.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HubX.Library.Socket.Object +{ + public enum EnumObjectType + { + NONE = 0, + Client = 1, + } +} diff --git a/Projects/HubX/HubX.Library/Socket/Object/ObjectManager.cs b/Projects/HubX/HubX.Library/Socket/Object/ObjectManager.cs new file mode 100644 index 0000000..8812d84 --- /dev/null +++ b/Projects/HubX/HubX.Library/Socket/Object/ObjectManager.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HubX.Library.Socket.Object +{ + public class ObjectManager + { + public static ObjectManager Instance { get; } = new ObjectManager(); + + object _lock = new object(); + Dictionary _players = new Dictionary(); + + // [UNUSED(1)][TYPE(7)][ID(24)] + int _counter = 0; + + public T Add() where T : Client, new() + { + T gameObject = new T(); + + lock (_lock) + { + gameObject.Id = GenerateId(gameObject.ObjectType); + + if (gameObject.ObjectType == EnumObjectType.Client) + { + _players.Add(gameObject.Id, gameObject as Client); + } + } + + return gameObject; + } + + int GenerateId(EnumObjectType type) + { + lock (_lock) + { + return ((int)type << 24) | (_counter++); + } + } + + public static EnumObjectType GetObjectTypeById(int id) + { + int type = (id >> 24) & 0x7F; + return (EnumObjectType)type; + } + + public bool Remove(int objectId) + { + EnumObjectType objectType = GetObjectTypeById(objectId); + + lock (_lock) + { + if (objectType == EnumObjectType.Client) + return _players.Remove(objectId); + } + + return false; + } + + public Client Find(int objectId) + { + EnumObjectType objectType = GetObjectTypeById(objectId); + + lock (_lock) + { + if (objectType == EnumObjectType.Client) + { + Client player = null; + if (_players.TryGetValue(objectId, out player)) + return player; + } + } + + return null; + } + } +} diff --git a/Projects/HubX/HubX.Library/Socket/Packet/EnumMessageId.cs b/Projects/HubX/HubX.Library/Socket/Packet/EnumMessageId.cs new file mode 100644 index 0000000..20c5e92 --- /dev/null +++ b/Projects/HubX/HubX.Library/Socket/Packet/EnumMessageId.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HubX.Library.Socket.Packet +{ + public enum EnumMessageId + { + //C2S : Client to Server + //S2C : Server to Client + + //unique key CRUD + C2S_INSERT_UniqueKey = 10, + S2C_INSERT_UniqueKey = 11, + C2S_SELECT_UniqueKey = 12, + S2C_SELECT_UniqueKey = 13, + C2S_UPDATE_UniqueKey = 14, + S2C_UPDATE_UniqueKey = 15, + C2S_DELETE_UniqueKey = 16, + S2C_DELETE_UniqueKey = 17, + } + + public enum EnumMessageResult + { + None = 0, + + Success = 10, + Failed = 10, + Error = 11, + } +} diff --git a/Projects/HubX/HubX.Library/Socket/Packet/PacketHandler.cs b/Projects/HubX/HubX.Library/Socket/Packet/PacketHandler.cs new file mode 100644 index 0000000..245a75d --- /dev/null +++ b/Projects/HubX/HubX.Library/Socket/Packet/PacketHandler.cs @@ -0,0 +1,43 @@ +using HubX.Library.Socket.Object; +using HubX.Library.Socket.Session; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; +using SystemX.Core.Communication; + +namespace HubX.Library.Socket.Packet +{ + + public class PacketHandler + { + public static void C2S_INSERT_UniqueKeyHandler(PacketSession session, IMessage packet) + { + C2S_INSERT_UniqueKey movePacket = packet as C2S_INSERT_UniqueKey; + ClientSession clientSession = session as ClientSession; + + Client client = clientSession.Client; + if (client == null) + return; + } + + public static void C_SkillHandler(PacketSession session, IMessage packet) + { + //C_Skill skillPacket = packet as C_Skill; + //ClientSession clientSession = session as ClientSession; + + //Player player = clientSession.MyPlayer; + //if (player == null) + // return; + + //GameRoom room = player.Room; + //if (room == null) + // return; + + //room.Push(room.HandleSkill, player, skillPacket); + } + } + +} diff --git a/Projects/HubX/HubX.Library/Socket/Packet/Protocol.cs b/Projects/HubX/HubX.Library/Socket/Packet/Protocol.cs new file mode 100644 index 0000000..3909a35 --- /dev/null +++ b/Projects/HubX/HubX.Library/Socket/Packet/Protocol.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HubX.Library.Socket.Packet +{ + public interface IMessage + { + } + + public class C2S : IMessage + { + public EnumMessageId MessageId { get; set; } + } + + public class S2C : IMessage + { + public EnumMessageId MessageId { get; set; } + + public EnumMessageResult Result { get; set; } + } + + public sealed class C2S_INSERT_UniqueKey : C2S + { + public string Identity { get; set; } + + public string Data1 { get; set; } + public string Data2 { get; set; } + public string Data3 { get; set; } + public string Data4 { get; set; } + public string Data5 { get; set; } + } + + public sealed class S2C_INSERT_UniqueKey : S2C + { + public string Identity { get; set; } + + public string Data1 { get; set; } + public string Data2 { get; set; } + public string Data3 { get; set; } + public string Data4 { get; set; } + public string Data5 { get; set; } + } +} diff --git a/Projects/HubX/HubX.Library/Socket/Packet/ServerPacketManager.cs b/Projects/HubX/HubX.Library/Socket/Packet/ServerPacketManager.cs new file mode 100644 index 0000000..62e5426 --- /dev/null +++ b/Projects/HubX/HubX.Library/Socket/Packet/ServerPacketManager.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SystemX.Core.Communication; + +namespace HubX.Library.Socket.Packet +{ + public class PacketManager + { + #region Singleton + static PacketManager _instance = new PacketManager(); + public static PacketManager Instance { get { return _instance; } } + #endregion + + PacketManager() + { + Register(); + } + + Dictionary, ushort>> _onRecv = new Dictionary, ushort>>(); + Dictionary> _handler = new Dictionary>(); + + public Action CustomHandler { get; set; } + + public void Register() + { + _onRecv.Add((ushort)EnumMessageId.C2S_INSERT_UniqueKey, MakePacket); + _handler.Add((ushort)EnumMessageId.C2S_INSERT_UniqueKey, PacketHandler.C2S_INSERT_UniqueKeyHandler); + } + + public void OnRecvPacket(PacketSession session, ArraySegment buffer) + { + ushort count = 0; + + ushort size = BitConverter.ToUInt16(buffer.Array, buffer.Offset); + count += 2; + ushort id = BitConverter.ToUInt16(buffer.Array, buffer.Offset + count); + count += 2; + + Action, ushort> action = null; + if (_onRecv.TryGetValue(id, out action)) + action.Invoke(session, buffer, id); + } + + void MakePacket(PacketSession session, ArraySegment buffer, ushort id) where T : IMessage, new() + { + T pkt = new T(); + //pkt.MergeFrom(buffer.Array, buffer.Offset + 4, buffer.Count - 4); + + if (CustomHandler != null) + { + CustomHandler.Invoke(session, pkt, id); + } + else + { + Action action = null; + if (_handler.TryGetValue(id, out action)) + action.Invoke(session, pkt); + } + } + + public Action GetPacketHandler(ushort id) + { + Action action = null; + if (_handler.TryGetValue(id, out action)) + return action; + return null; + } + } +} diff --git a/Projects/HubX/HubX.Library/Socket/Session/ClientSession.cs b/Projects/HubX/HubX.Library/Socket/Session/ClientSession.cs new file mode 100644 index 0000000..e11dad6 --- /dev/null +++ b/Projects/HubX/HubX.Library/Socket/Session/ClientSession.cs @@ -0,0 +1,56 @@ +using HubX.Library.Socket.Object; +using HubX.Library.Socket.Packet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; +using SystemX.Core.Communication; + +namespace HubX.Library.Socket.Session +{ + public class ClientSession : PacketSession + { + public Client Client { get; set; } + public int SessionId { get; set; } + + public void Send(IMessage packet) + { + //string msgName = packet.Descriptor.Name.Replace("_", string.Empty); + //EnumMessageId msgId = (EnumMessageId)Enum.Parse(typeof(EnumMessageId), msgName); + //ushort size = (ushort)packet.CalculateSize(); + //byte[] sendBuffer = new byte[size + 4]; + //Array.Copy(BitConverter.GetBytes((ushort)(size + 4)), 0, sendBuffer, 0, sizeof(ushort)); + //Array.Copy(BitConverter.GetBytes((ushort)msgId), 0, sendBuffer, 2, sizeof(ushort)); + //Array.Copy(packet.ToByteArray(), 0, sendBuffer, 4, size); + //Send(new ArraySegment(sendBuffer)); + } + + public override void OnConnected(EndPoint endPoint) + { + Log4net.WriteLine($"OnConnected : {endPoint}", LogType.SOCKET); + Client = ObjectManager.Instance.Add(); + { + Client.Session = this; + } + } + + public override void OnRecvPacket(ArraySegment buffer) + { + Log4net.WriteLine($"OnRecvPacket : {Encoding.UTF8.GetString(buffer)}", LogType.SOCKET); + PacketManager.Instance.OnRecvPacket(this, buffer); + } + + public override void OnDisconnected(EndPoint endPoint) + { + Log4net.WriteLine($"OnDisconnected : {endPoint}", LogType.SOCKET); + } + + public override void OnSend(int numOfBytes) + { + //Console.WriteLine($"Transferred bytes: {numOfBytes}"); + } + } +} diff --git a/Projects/HubX/HubX.Library/Socket/Session/SessionManager.cs b/Projects/HubX/HubX.Library/Socket/Session/SessionManager.cs new file mode 100644 index 0000000..f409659 --- /dev/null +++ b/Projects/HubX/HubX.Library/Socket/Session/SessionManager.cs @@ -0,0 +1,54 @@ +using HubX.Library.Socket.Packet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SystemX.Core.Communication; + +namespace HubX.Library.Socket.Session +{ + public class SessionManager + { + static SessionManager _session = new SessionManager(); + public static SessionManager Instance { get { return _session; } } + + int _sessionId = 0; + Dictionary _sessions = new Dictionary(); + object _lock = new object(); + + public ClientSession Generate() + { + lock (_lock) + { + int sessionId = ++_sessionId; + + ClientSession session = new ClientSession(); + session.SessionId = sessionId; + _sessions.Add(sessionId, session); + + Log4net.WriteLine($"Connected : {sessionId}", LogType.SOCKET); + + return session; + } + } + + public ClientSession Find(int id) + { + lock (_lock) + { + ClientSession session = null; + _sessions.TryGetValue(id, out session); + return session; + } + } + + public void Remove(ClientSession session) + { + lock (_lock) + { + _sessions.Remove(session.SessionId); + } + } + } +} diff --git a/Projects/HubX/HubX.Server/HubX.Server.csproj b/Projects/HubX/HubX.Server/HubX.Server.csproj index d3bb312..2cc9165 100644 --- a/Projects/HubX/HubX.Server/HubX.Server.csproj +++ b/Projects/HubX/HubX.Server/HubX.Server.csproj @@ -6,10 +6,22 @@ enable + + 9999 + + + + 9999 + + + + + + ..\..\DLL\SystemX.Core.dll diff --git a/Projects/HubX/HubX.Server/Program.cs b/Projects/HubX/HubX.Server/Program.cs index c56fe2d..797a699 100644 --- a/Projects/HubX/HubX.Server/Program.cs +++ b/Projects/HubX/HubX.Server/Program.cs @@ -1,4 +1,7 @@ -using SystemX.Core.Log4net; +using HubX.Library.Socket.Session; +using HubX.Server; +using System.Net; +using SystemX.Core.Communication; var builder = WebApplication.CreateBuilder(args); @@ -21,6 +24,30 @@ if (app.Environment.IsDevelopment()) Log4net.WriteLine("Run"); Log4net.WriteLine("Custom LogLevel",LogType.DB); +WeatherForecast weatherForecast = new WeatherForecast(); +weatherForecast.Summary = "so hot"; +var strJson = weatherForecast.ToJson(); + +var deep = weatherForecast.DeepCopy(); +deep.Summary = "so cool"; + +var rr = strJson.ToObject(); + +Task.Run(async() => +{ + await Task.Delay(2000); + Listener _listener = new Listener(); + + // string host = Dns.GetHostName(); + IPHostEntry ipHost = Dns.GetHostEntry("127.0.0.1"); + IPAddress ipAddr = ipHost.AddressList[0]; + IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777); + + _listener.Init(endPoint, () => { return SessionManager.Instance.Generate(); }); + + Console.WriteLine("Listening..."); +}); + app.UseHttpsRedirection(); app.UseAuthorization(); diff --git a/Projects/HubX/HubX.Server/Properties/launchSettings.json b/Projects/HubX/HubX.Server/Properties/launchSettings.json index ceae9d3..aee3210 100644 --- a/Projects/HubX/HubX.Server/Properties/launchSettings.json +++ b/Projects/HubX/HubX.Server/Properties/launchSettings.json @@ -1,4 +1,31 @@ -{ +{ + "profiles": { + "http": { + "commandName": "Project", + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5103" + }, + "https": { + "commandName": "Project", + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7163;http://localhost:5103" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + }, "$schema": "http://json.schemastore.org/launchsettings.json", "iisSettings": { "windowsAuthentication": false, @@ -7,35 +34,5 @@ "applicationUrl": "http://localhost:33125", "sslPort": 44383 } - }, - "profiles": { - "http": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "http://localhost:5103", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "https://localhost:7163;http://localhost:5103", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } } -} +} \ No newline at end of file diff --git a/Projects/SystemX.Core/SystemX.Core/Communication/Http.cs b/Projects/SystemX.Core/SystemX.Core/Communication/Http.cs new file mode 100644 index 0000000..33cbbf2 --- /dev/null +++ b/Projects/SystemX.Core/SystemX.Core/Communication/Http.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http.Json; +using System.Text; +using System.Threading.Tasks; + +namespace SystemX.Core.Communication +{ + public class Http + { + /// + /// PostJsonAsync + /// + /// https://127.0.0.1:443 + /// Range 5~30 secconds + public virtual async Task PostJsonAsync(string url, REQUEST request, short timeOutSeconds = 5) where REQUEST : class where RESPONSE : class + { + RESPONSE? response = default(RESPONSE); + Guid guid = Guid.NewGuid(); + + using (HttpClient httpClient = new HttpClient(GetClientHandler())) + { + int retry = 0; + while (true) + { + await Task.Delay(1); + try + { + var timeOutSec = SetTimeout(timeOutSeconds); + httpClient.Timeout = new TimeSpan(0, 0, timeOutSec); + httpClient.BaseAddress = new Uri($"{url}"); + + Log4net.WriteLine($"[POST] Request({guid})::{url}{Environment.NewLine}{request?.ToJson()}", LogType.HTTP); + + DateTime requestTime = DateTime.Now; + var res = await httpClient.PostAsJsonAsync(url, request); + response = await res.Content.ReadFromJsonAsync(); + + Log4net.WriteLine($"[POST] Rseponse({guid}) ({(DateTime.Now - requestTime).TotalSeconds} sec)::{url}{Environment.NewLine}{response?.ToJson()}", LogType.HTTP); + break; + } + catch (Exception e) + { + Log4net.WriteLine(e); + retry += 1; + } + + if (retry > 1) + break; + } + } + + return response; + } + + /// + /// GetJsonAsnyc + /// + /// https://127.0.0.1:443 + /// Range 5~30 secconds + public virtual async Task GetJsonAsync(string url, short timeOutSeconds = 10) where RESPONSE : class + { + RESPONSE? response = default(RESPONSE); + Guid guid = Guid.NewGuid(); + + using (HttpClient httpClient = new HttpClient(GetClientHandler())) + { + try + { + var timeOutSec = SetTimeout(timeOutSeconds); + httpClient.Timeout = new TimeSpan(0, 0, timeOutSec); + httpClient.BaseAddress = new Uri($"{url}"); + + Log4net.WriteLine($"[GET] Request({guid})::{url}", LogType.HTTP); + + DateTime requestTime = DateTime.Now; + response = await httpClient.GetFromJsonAsync(url); + + Log4net.WriteLine($"[GET] Rseponse({guid}) ({(DateTime.Now - requestTime).TotalSeconds} sec)::{url}", LogType.HTTP); + } + catch (Exception e) + { + Log4net.WriteLine(e); + } + } + + return response; + } + + protected HttpClientHandler GetClientHandler() + { + HttpClientHandler clientHandler = new HttpClientHandler(); + clientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) => + { + return true; + }; + + return clientHandler; + } + + protected short SetTimeout(short timeOutSeconds) + { + short timeoutMin = 5; + short timeoutMax = 30; + + timeOutSeconds = Math.Clamp(timeOutSeconds, timeoutMin, timeoutMax); + + return timeOutSeconds; + } + } +} diff --git a/Projects/SystemX.Core/SystemX.Core/Communication/Socket/Listener.cs b/Projects/SystemX.Core/SystemX.Core/Communication/Socket/Listener.cs new file mode 100644 index 0000000..ed7d124 --- /dev/null +++ b/Projects/SystemX.Core/SystemX.Core/Communication/Socket/Listener.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using static System.Collections.Specialized.BitVector32; + +namespace SystemX.Core.Communication +{ + public class Listener + { + Socket _listenSocket; + Func _sessionFactory; + + public void Init(IPEndPoint endPoint, Func sessionFactory, int register = 10, int backlog = 100) + { + _listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + _sessionFactory += sessionFactory; + + _listenSocket.Bind(endPoint); + + // backlog : 최대 대기수 + _listenSocket.Listen(backlog); + + for (int i = 0; i < register; i++) + { + SocketAsyncEventArgs args = new SocketAsyncEventArgs(); + args.Completed += new EventHandler(OnAcceptCompleted); + RegisterAccept(args); + } + } + + void RegisterAccept(SocketAsyncEventArgs args) + { + args.AcceptSocket = null; + + bool pending = _listenSocket.AcceptAsync(args); + if (pending == false) + OnAcceptCompleted(null, args); + } + + void OnAcceptCompleted(object sender, SocketAsyncEventArgs args) + { + if (args.SocketError == SocketError.Success) + { + Session session = _sessionFactory.Invoke(); + session.Start(args.AcceptSocket); + session.OnConnected(args.AcceptSocket.RemoteEndPoint); + } + else + { + Log4net.WriteLine(args.SocketError.ToString(), LogType.Error); + } + + RegisterAccept(args); + } + } +} diff --git a/Projects/SystemX.Core/SystemX.Core/Communication/Socket/RecvBuffer.cs b/Projects/SystemX.Core/SystemX.Core/Communication/Socket/RecvBuffer.cs new file mode 100644 index 0000000..29f67bb --- /dev/null +++ b/Projects/SystemX.Core/SystemX.Core/Communication/Socket/RecvBuffer.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SystemX.Core.Communication +{ + public class RecvBuffer + { + // [r][][w][][][][][][][] + ArraySegment _buffer; + int _readPos; + int _writePos; + + public RecvBuffer(int bufferSize) + { + _buffer = new ArraySegment(new byte[bufferSize], 0, bufferSize); + } + + public int DataSize { get { return _writePos - _readPos; } } + public int FreeSize { get { return _buffer.Count - _writePos; } } + + public ArraySegment ReadSegment + { + get { return new ArraySegment(_buffer.Array, _buffer.Offset + _readPos, DataSize); } + } + + public ArraySegment WriteSegment + { + get { return new ArraySegment(_buffer.Array, _buffer.Offset + _writePos, FreeSize); } + } + + public void Clean() + { + int dataSize = DataSize; + if (dataSize == 0) + { + // 남은 데이터가 없으면 복사하지 않고 커서 위치만 리셋 + _readPos = _writePos = 0; + } + else + { + // 남은 찌끄레기가 있으면 시작 위치로 복사 + Array.Copy(_buffer.Array, _buffer.Offset + _readPos, _buffer.Array, _buffer.Offset, dataSize); + _readPos = 0; + _writePos = dataSize; + } + } + + public bool OnRead(int numOfBytes) + { + if (numOfBytes > DataSize) + return false; + + _readPos += numOfBytes; + return true; + } + + public bool OnWrite(int numOfBytes) + { + if (numOfBytes > FreeSize) + return false; + + _writePos += numOfBytes; + return true; + } + } +} diff --git a/Projects/SystemX.Core/SystemX.Core/Communication/Socket/Session.cs b/Projects/SystemX.Core/SystemX.Core/Communication/Socket/Session.cs new file mode 100644 index 0000000..d4edf48 --- /dev/null +++ b/Projects/SystemX.Core/SystemX.Core/Communication/Socket/Session.cs @@ -0,0 +1,239 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace SystemX.Core.Communication +{ + public abstract class PacketSession : Session + { + public static readonly int HeaderSize = 2; + + // [size(2)][packetId(2)][ ... ][size(2)][packetId(2)][ ... ] + public sealed override int OnRecv(ArraySegment buffer) + { + int processLen = 0; + int packetCount = 0; + + while (true) + { + // 최소한 헤더는 파싱할 수 있는지 확인 + if (buffer.Count < HeaderSize) + break; + + // 패킷이 완전체로 도착했는지 확인 + ushort dataSize = BitConverter.ToUInt16(buffer.Array, buffer.Offset); + if (buffer.Count < dataSize) + break; + + // 여기까지 왔으면 패킷 조립 가능 + OnRecvPacket(new ArraySegment(buffer.Array, buffer.Offset, dataSize)); + packetCount++; + + processLen += dataSize; + buffer = new ArraySegment(buffer.Array, buffer.Offset + dataSize, buffer.Count - dataSize); + } + + return processLen; + } + + public abstract void OnRecvPacket(ArraySegment buffer); + } + + public abstract class Session + { + Socket _socket; + int _disconnected = 0; + + RecvBuffer _recvBuffer = new RecvBuffer(65535); + + object _lock = new object(); + Queue> _sendQueue = new Queue>(); + List> _pendingList = new List>(); + SocketAsyncEventArgs _sendArgs = new SocketAsyncEventArgs(); + SocketAsyncEventArgs _recvArgs = new SocketAsyncEventArgs(); + + public abstract void OnConnected(EndPoint endPoint); + public abstract int OnRecv(ArraySegment buffer); + public abstract void OnSend(int numOfBytes); + public abstract void OnDisconnected(EndPoint endPoint); + + void Clear() + { + lock (_lock) + { + _sendQueue.Clear(); + _pendingList.Clear(); + } + } + + public void Start(Socket socket) + { + Log4net.WriteLine("Session Start"); + + _socket = socket; + + _recvArgs.Completed += new EventHandler(OnRecvCompleted); + _sendArgs.Completed += new EventHandler(OnSendCompleted); + + RegisterRecv(); + } + + public void Send(List> sendBuffList) + { + if (sendBuffList.Count == 0) + return; + + lock (_lock) + { + foreach (ArraySegment sendBuff in sendBuffList) + _sendQueue.Enqueue(sendBuff); + + if (_pendingList.Count == 0) + RegisterSend(); + } + } + + public void Send(ArraySegment sendBuff) + { + lock (_lock) + { + _sendQueue.Enqueue(sendBuff); + if (_pendingList.Count == 0) + RegisterSend(); + } + } + + public void Disconnect() + { + if (Interlocked.Exchange(ref _disconnected, 1) == 1) + return; + + OnDisconnected(_socket.RemoteEndPoint); + _socket.Shutdown(SocketShutdown.Both); + _socket.Close(); + Clear(); + } + + #region 네트워크 통신 + + void RegisterSend() + { + if (_disconnected == 1) + return; + + while (_sendQueue.Count > 0) + { + ArraySegment buff = _sendQueue.Dequeue(); + _pendingList.Add(buff); + } + _sendArgs.BufferList = _pendingList; + + try + { + bool pending = _socket.SendAsync(_sendArgs); + if (pending == false) + OnSendCompleted(null, _sendArgs); + } + catch (Exception e) + { + Log4net.WriteLine($"RegisterSend Failed {e}", LogType.Error); + } + } + + void OnSendCompleted(object sender, SocketAsyncEventArgs args) + { + lock (_lock) + { + if (args.BytesTransferred > 0 && args.SocketError == SocketError.Success) + { + try + { + _sendArgs.BufferList = null; + _pendingList.Clear(); + + OnSend(_sendArgs.BytesTransferred); + + if (_sendQueue.Count > 0) + RegisterSend(); + } + catch (Exception e) + { + Log4net.WriteLine($"OnSendCompleted Failed {e}", LogType.Error); + } + } + else + { + Disconnect(); + } + } + } + + void RegisterRecv() + { + if (_disconnected == 1) + return; + + _recvBuffer.Clean(); + ArraySegment segment = _recvBuffer.WriteSegment; + _recvArgs.SetBuffer(segment.Array, segment.Offset, segment.Count); + + try + { + bool pending = _socket.ReceiveAsync(_recvArgs); + if (pending == false) + OnRecvCompleted(null, _recvArgs); + } + catch (Exception e) + { + Log4net.WriteLine($"RegisterRecv Failed {e}", LogType.Error); + } + } + + void OnRecvCompleted(object sender, SocketAsyncEventArgs args) + { + if (args.BytesTransferred > 0 && args.SocketError == SocketError.Success) + { + try + { + // Write 커서 이동 + if (_recvBuffer.OnWrite(args.BytesTransferred) == false) + { + Disconnect(); + return; + } + + // 컨텐츠 쪽으로 데이터를 넘겨주고 얼마나 처리했는지 받는다 + int processLen = OnRecv(_recvBuffer.ReadSegment); + if (processLen < 0 || _recvBuffer.DataSize < processLen) + { + Disconnect(); + return; + } + + // Read 커서 이동 + if (_recvBuffer.OnRead(processLen) == false) + { + Disconnect(); + return; + } + + RegisterRecv(); + } + catch (Exception e) + { + Log4net.WriteLine($"OnRecvCompleted Failed {e}", LogType.Error); + } + } + else + { + Disconnect(); + } + } + + #endregion + } +} diff --git a/Projects/SystemX.Core/SystemX.Core/DB/DataBase.cs b/Projects/SystemX.Core/SystemX.Core/DB/DataBase.cs new file mode 100644 index 0000000..8080bea --- /dev/null +++ b/Projects/SystemX.Core/SystemX.Core/DB/DataBase.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace SystemX.Core.DB +{ + public class DataBase + { + [JsonPropertyName("IP")] + public string? IP { get; set; } + + [JsonPropertyName("Port")] + public int Port { get; set; } + + [JsonPropertyName("DBName")] + public string? DBName { get; set; } + + [JsonPropertyName("DBID")] + public int DBID { get; set; } + + [JsonPropertyName("DBContext")] + public string? DBContext { get; set; } + + [JsonPropertyName("UserID")] + public string? UserID { get; set; } + + [JsonPropertyName("Password")] + public string? Password { get; set; } + } +} diff --git a/Projects/SystemX.Core/SystemX.Core/DB/EFCore.cs b/Projects/SystemX.Core/SystemX.Core/DB/EFCore.cs new file mode 100644 index 0000000..bb3a997 --- /dev/null +++ b/Projects/SystemX.Core/SystemX.Core/DB/EFCore.cs @@ -0,0 +1,106 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SystemX.Core.DB +{ + public static class EFCore + { + /// + /// Get SqlServer Connection String + /// + public static string ConvertToConnectionString(this DataBase dbConfig) + { + return $"server={dbConfig.IP},{dbConfig.Port}; user id={dbConfig.UserID}; password={dbConfig.Password}; database={dbConfig.DBName}; TrustServerCertificate=true;"; + } + + public static IEnumerable? GetEntity(this DbContext dbContext) where TEntity : class + { + IEnumerable? entity = default; + + var type = dbContext.GetType(); + try + { + foreach (var prop in type.GetProperties()) + { + string propertyFullName = $"{prop.PropertyType.FullName}"; + if (propertyFullName.ToLower().Contains(typeof(TEntity).Name.ToLower())) + { + entity = prop.GetValue(dbContext) as IEnumerable; + break; + } + } + } + catch (Exception ex) + { + Log4net.WriteLine(ex); + } + + return entity; + } + + #region Transaction + public static IDbContextTransaction CreateTransaction(this DbContext dbContext) + { + return dbContext.Database.BeginTransaction(); + } + + public static bool CloseTransaction(this DbContext dbContext, IDbContextTransaction transaction) + { + bool result = false; + try + { + dbContext.SaveChanges(); + transaction.Commit(); + result = true; + + Log4net.WriteLine("Transaction Commit", LogType.Debug); + } + catch (Exception ex) + { + transaction.Rollback(); + Log4net.WriteLine("Transaction Rollback", LogType.Error); + Log4net.WriteLine(ex); + } + transaction.Dispose(); + + return result; + } + #endregion + + #region Transaction Async + public static async Task CreateTransactionAsync(this DbContext dbContext) + { + return await dbContext.Database.BeginTransactionAsync(); + } + + public static async Task CloseTransactionAsync(this DbContext dbContext, IDbContextTransaction transaction) + { + bool result = false; + try + { + await dbContext.SaveChangesAsync(); + await transaction.CommitAsync(); + result = true; + + Log4net.WriteLine("Transaction Commit", LogType.Debug); + } + catch (Exception ex) + { + await transaction.RollbackAsync(); + Log4net.WriteLine("Transaction Rollback", LogType.Error); + Log4net.WriteLine(ex); + } + await transaction.DisposeAsync(); + + return result; + } + #endregion + } + + +} diff --git a/Projects/SystemX.Core/SystemX.Core/Log4net/Log4net.cs b/Projects/SystemX.Core/SystemX.Core/Log4net/Log4net.cs index d7ea1a8..8d10913 100644 --- a/Projects/SystemX.Core/SystemX.Core/Log4net/Log4net.cs +++ b/Projects/SystemX.Core/SystemX.Core/Log4net/Log4net.cs @@ -7,240 +7,239 @@ using System.Reflection; using System.Text; using System.Threading.Tasks; -namespace SystemX.Core.Log4net + +#region LogType +public enum LogType { - #region LogType - public enum LogType + //default level + Info = 0, + Warn = 1, + Error = 2, + Debug = 3, + Fatal = 4, + + //custom level + DB = 10, + + HTTP = 20, + SOCKET = 21, +} +#endregion + +#region CustomLevel +public static class Log4netCustomLevel +{ + public static readonly log4net.Core.Level DB = new log4net.Core.Level(10010, LogType.DB.ToString()); + public static readonly log4net.Core.Level HTTP = new log4net.Core.Level(10020, LogType.HTTP.ToString()); + public static readonly log4net.Core.Level SOCKET = new log4net.Core.Level(10021, LogType.SOCKET.ToString()); + + public static void SetCustomLevel(ILoggerRepository repo) { - //default level - Info = 0, - Warn = 1, - Error = 2, - Debug = 3, - Fatal = 4, - - //custom level - DB = 10, - - HTTP = 20, - SOCKET = 21, - } - #endregion - - #region CustomLevel - public static class Log4netCustomLevel - { - public static readonly log4net.Core.Level DB = new log4net.Core.Level(10010, LogType.DB.ToString()); - public static readonly log4net.Core.Level HTTP = new log4net.Core.Level(10020, LogType.HTTP.ToString()); - public static readonly log4net.Core.Level SOCKET = new log4net.Core.Level(10021, LogType.SOCKET.ToString()); - - public static void SetCustomLevel(ILoggerRepository repo) - { - repo.LevelMap.Add(DB); - repo.LevelMap.Add(HTTP); - repo.LevelMap.Add(SOCKET); - } - } - #endregion - - public static class Log4net - { - private static ILog? Manager; - - private static ILoggerRepository repo = LogManager.GetRepository(); - - public static bool IsConfigLoad { get; set; } = false; - - - - static Log4net() - { - Console.WriteLine("log4net constructor"); - if (File.Exists("./log4net.config") == false) - { - File.WriteAllText("log4net.config", Config); - } - - IsConfigLoad = OpenConfig(@"./log4net.config"); - } - - private static bool OpenConfig(string path) - { - bool result = true; - - try - { - Log4netCustomLevel.SetCustomLevel(repo); - - if (File.Exists(path) == false) - result = false; - - log4net.Config.XmlConfigurator.Configure(new FileInfo(path)); - Manager = LogManager.GetLogger(""); - } - catch (Exception e) - { - Console.WriteLine("Log4net Init Error"); - Console.WriteLine(e.Message); - result = false; - } - - return result; - } - - public static void WriteLine(T log, LogType logType = LogType.Info) - { - if (IsConfigLoad == false) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine($"[Log4net Initialize Error] {log}"); - return; - } - - switch (logType) - { - case LogType.Info: - { - Manager?.Info(log); - break; - } - case LogType.Warn: - { - Manager?.Warn(log); - break; - } - case LogType.Error: - { - Manager?.Error(log); - break; - } - case LogType.Debug: - { - Manager?.Debug(log); - break; - } - case LogType.Fatal: - { - Manager?.Fatal(log); - break; - } - case LogType.DB: - { - Type? t = MethodBase.GetCurrentMethod()?.DeclaringType; - if (t != null) - { - Manager?.Logger.Log(t, Log4netCustomLevel.DB, log, null); - } - break; - } - case LogType.HTTP: - { - Type? t = MethodBase.GetCurrentMethod()?.DeclaringType; - if (t != null) - { - Manager?.Logger.Log(t, Log4netCustomLevel.HTTP, log, null); - } - break; - } - case LogType.SOCKET: - { - Type? t = MethodBase.GetCurrentMethod()?.DeclaringType; - if (t != null) - { - Manager?.Logger.Log(t, Log4netCustomLevel.SOCKET, log, null); - } - break; - } - } - } - - public static void WriteLine(Exception? ex) - { - WriteLine(ex?.Message, LogType.Error); - } - - - #region Config - static string Config = @$" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"; - #endregion + repo.LevelMap.Add(DB); + repo.LevelMap.Add(HTTP); + repo.LevelMap.Add(SOCKET); } } +#endregion + +public static class Log4net +{ + private static ILog? Manager; + + private static ILoggerRepository repo = LogManager.GetRepository(); + + public static bool IsConfigLoad { get; set; } = false; + + + + static Log4net() + { + Console.WriteLine("log4net constructor"); + if (File.Exists("./log4net.config") == false) + { + File.WriteAllText("log4net.config", Config); + } + + IsConfigLoad = OpenConfig(@"./log4net.config"); + } + + private static bool OpenConfig(string path) + { + bool result = true; + + try + { + Log4netCustomLevel.SetCustomLevel(repo); + + if (File.Exists(path) == false) + result = false; + + log4net.Config.XmlConfigurator.Configure(new FileInfo(path)); + Manager = LogManager.GetLogger(""); + } + catch (Exception e) + { + Console.WriteLine("Log4net Init Error"); + Console.WriteLine(e.Message); + result = false; + } + + return result; + } + + public static void WriteLine(T log, LogType logType = LogType.Info) + { + if (IsConfigLoad == false) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($"[Log4net Initialize Error] {log}"); + return; + } + + switch (logType) + { + case LogType.Info: + { + Manager?.Info(log); + break; + } + case LogType.Warn: + { + Manager?.Warn(log); + break; + } + case LogType.Error: + { + Manager?.Error(log); + break; + } + case LogType.Debug: + { + Manager?.Debug(log); + break; + } + case LogType.Fatal: + { + Manager?.Fatal(log); + break; + } + case LogType.DB: + { + Type? t = MethodBase.GetCurrentMethod()?.DeclaringType; + if (t != null) + { + Manager?.Logger.Log(t, Log4netCustomLevel.DB, log, null); + } + break; + } + case LogType.HTTP: + { + Type? t = MethodBase.GetCurrentMethod()?.DeclaringType; + if (t != null) + { + Manager?.Logger.Log(t, Log4netCustomLevel.HTTP, log, null); + } + break; + } + case LogType.SOCKET: + { + Type? t = MethodBase.GetCurrentMethod()?.DeclaringType; + if (t != null) + { + Manager?.Logger.Log(t, Log4netCustomLevel.SOCKET, log, null); + } + break; + } + } + } + + public static void WriteLine(Exception? ex) + { + WriteLine(ex?.Message, LogType.Error); + } + + + #region Config + static string Config = @$" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"; + #endregion +} + /* log4net 지정 가능 색상 diff --git a/Projects/SystemX.Core/SystemX.Core/SystemX.Core.csproj b/Projects/SystemX.Core/SystemX.Core/SystemX.Core.csproj index 1d7f086..c96a53d 100644 --- a/Projects/SystemX.Core/SystemX.Core/SystemX.Core.csproj +++ b/Projects/SystemX.Core/SystemX.Core/SystemX.Core.csproj @@ -17,6 +17,7 @@ + diff --git a/Projects/SystemX.Core/SystemX.Core/Utils/DateTimeUtils.cs b/Projects/SystemX.Core/SystemX.Core/Utils/DateTimeUtils.cs new file mode 100644 index 0000000..212a657 --- /dev/null +++ b/Projects/SystemX.Core/SystemX.Core/Utils/DateTimeUtils.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +public static class DateTimeUtils +{ + public static long ToUnixTime(this DateTime dateTime) + { + DateTimeOffset dto = new DateTimeOffset(dateTime.ToUniversalTime()); + return dto.ToUnixTimeSeconds(); + } +} + diff --git a/Projects/SystemX.Core/SystemX.Core/Json/JsonUtils.cs b/Projects/SystemX.Core/SystemX.Core/Utils/JsonUtils.cs similarity index 97% rename from Projects/SystemX.Core/SystemX.Core/Json/JsonUtils.cs rename to Projects/SystemX.Core/SystemX.Core/Utils/JsonUtils.cs index fab37aa..4cda787 100644 --- a/Projects/SystemX.Core/SystemX.Core/Json/JsonUtils.cs +++ b/Projects/SystemX.Core/SystemX.Core/Utils/JsonUtils.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using SystemX.Core.Log4net; public static class JsonUtils {