diff --git a/Projects/WebApi/WebApi.Project.UniqueKeyApi/Program.cs b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Program.cs index 5ec290b..4e1b50c 100644 --- a/Projects/WebApi/WebApi.Project.UniqueKeyApi/Program.cs +++ b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Program.cs @@ -89,8 +89,8 @@ if (app.Environment.IsDevelopment()) app.UseSwaggerUI(); } -//TaskSocket taskSocket = new TaskSocket(); -//taskSocket?.Run(socketPort); +TaskSocket taskSocket = new TaskSocket(); +taskSocket?.Run(socketPort); app.UseAuthentication(); app.UseHttpsRedirection(); diff --git a/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Object/Client.cs b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Object/Client.cs new file mode 100644 index 0000000..755853f --- /dev/null +++ b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Object/Client.cs @@ -0,0 +1,24 @@ +using WebApi.Project.UniqueKeyApi.Socket.Session; + +namespace WebApi.Project.UniqueKeyApi.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/WebApi/WebApi.Project.UniqueKeyApi/Socket/Object/EnumObjectType.cs b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Object/EnumObjectType.cs new file mode 100644 index 0000000..8554ece --- /dev/null +++ b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Object/EnumObjectType.cs @@ -0,0 +1,8 @@ +namespace WebApi.Project.UniqueKeyApi.Socket.Object +{ + public enum EnumObjectType + { + NONE = 0, + Client = 1, + } +} diff --git a/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Object/ObjectManager.cs b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Object/ObjectManager.cs new file mode 100644 index 0000000..95e88a0 --- /dev/null +++ b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Object/ObjectManager.cs @@ -0,0 +1,74 @@ +namespace WebApi.Project.UniqueKeyApi.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/WebApi/WebApi.Project.UniqueKeyApi/Socket/Packet/EnumMessageId.cs b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Packet/EnumMessageId.cs new file mode 100644 index 0000000..1e11956 --- /dev/null +++ b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Packet/EnumMessageId.cs @@ -0,0 +1,27 @@ +namespace WebApi.Project.UniqueKeyApi.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/WebApi/WebApi.Project.UniqueKeyApi/Socket/Packet/PacketHandler.cs b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Packet/PacketHandler.cs new file mode 100644 index 0000000..595e165 --- /dev/null +++ b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Packet/PacketHandler.cs @@ -0,0 +1,178 @@ +using System.Text; +using SystemX.Core.Communication; +using WebApi.Project.UniqueKeyApi.Models; +using WebApi.Project.UniqueKeyApi.Socket.Object; +using WebApi.Project.UniqueKeyApi.Socket.Session; + +namespace WebApi.Project.UniqueKeyApi.Socket.Packet +{ + public class PacketHandler + { + public static async void C2S_INSERT_UniqueKeyHandler(PacketSession session, ArraySegment buffer) + { + var recvData = Encoding.UTF8.GetString(buffer); + + //json으로 요청인지 확인 + bool isJsonRequest = true; + + //convert to object + var jsonObject = recvData.ToObject(); + //json 요청 아닐때 변환 + if (jsonObject == null) + { + var recvDataList = recvData.Split(","); + jsonObject = new C2S_INSERT_UniqueKey + { + Identity = recvDataList[0], + Data1 = recvDataList[1], + Data2 = recvDataList[2], + Data3 = recvDataList[3], + Data4 = recvDataList[4], + Data5 = recvDataList[5], + }; + isJsonRequest = false; + } + + string result = string.Empty; + //insert DB + if (jsonObject != null) + { + Request_InsertUniqueKey request = new Request_InsertUniqueKey(); + request.Identity = jsonObject.Identity; + request.Data1 = jsonObject.Data1; + request.Data2 = jsonObject.Data2; + request.Data3 = jsonObject.Data3; + request.Data4 = jsonObject.Data4; + request.Data5 = jsonObject.Data5; + + await Task.Run(async () => + { + SystemX.Core.Communication.Http http = new(); + var res = await http.PostJsonAsync("https://127.0.0.1:9000/UniqueKey/InsertUniqueKey", request); + result = res.ToJson(); + + //json 요청이 아니면 변환 + if (isJsonRequest == false) + { + if (res != null) + result = $"{res.Identity},{res.Result}"; + } + }); + } + + ClientSession clientSession = session as ClientSession; + Client client = clientSession.Client; + if (client == null) + return; + + client.Session.Send(Encoding.UTF8.GetBytes(result), EnumMessageId.S2C_INSERT_UniqueKey); + } + + public static async void C2S_SELECT_UniqueKeyHandler(PacketSession session, ArraySegment buffer) + { + var recvData = Encoding.UTF8.GetString(buffer); + + //json으로 요청인지 확인 + bool isJsonRequest = true; + + //convert to object + var jsonObject = recvData.ToObject(); + //json 요청 아닐때 변환 + if (jsonObject == null) + { + var recvDataList = recvData.Split(","); + jsonObject = new C2S_SELECT_UniqueKey + { + Identity = recvDataList[0] + }; + isJsonRequest = false; + } + + string result = string.Empty; + //select DB + if (jsonObject != null) + { + Request_SelectUniqueKey request = new Request_SelectUniqueKey(); + request.Identity = jsonObject.Identity; + + await Task.Run(async () => + { + SystemX.Core.Communication.Http http = new(); + var res = await http.PostJsonAsync("https://127.0.0.1:9000/UniqueKey/SelectUniqueKey", request); + result = res.ToJson(); + + //json 요청이 아니면 변환 + if (isJsonRequest == false) + { + if (res != null) + result = $"{res.Identity},{res.Data1},{res.Data2},{res.Data3},{res.Data4},{res.Data5}"; + } + }); + } + + ClientSession clientSession = session as ClientSession; + Client client = clientSession.Client; + if (client == null) + return; + + client.Session.Send(Encoding.UTF8.GetBytes(result), EnumMessageId.S2C_SELECT_UniqueKey); + } + + public static async void C2S_UPDATE_UniqueKeyHandler(PacketSession session, ArraySegment buffer) + { + var recvData = Encoding.UTF8.GetString(buffer); + + //json으로 요청인지 확인 + bool isJsonRequest = true; + + //convert to object + var jsonObject = recvData.ToObject(); + //json 요청 아닐때 변환 + if (jsonObject == null) + { + var recvDataList = recvData.Split(","); + jsonObject = new C2S_UPDATE_UniqueKey + { + Identity = recvDataList[0], + Data1 = recvDataList[1], + Data2 = recvDataList[2], + Data3 = recvDataList[3], + Data4 = recvDataList[4], + Data5 = recvDataList[5], + }; + isJsonRequest = false; + } + + string result = string.Empty; + //insert DB + if (jsonObject != null) + { + Request_UpdateUniqueKey request = new Request_UpdateUniqueKey(); + request.Identity = jsonObject.Identity; + request.Data1 = jsonObject.Data1; + request.Data2 = jsonObject.Data2; + request.Data3 = jsonObject.Data3; + request.Data4 = jsonObject.Data4; + request.Data5 = jsonObject.Data5; + + SystemX.Core.Communication.Http http = new(); + var res = await http.PostJsonAsync("https://127.0.0.1:9000/UniqueKey/UpdateUniqueKey", request); + result = res.ToJson(); + + //json 요청이 아니면 변환 + if (isJsonRequest == false) + { + if (res != null) + result = $"{res.Identity},{res.Result}"; + } + } + + ClientSession clientSession = session as ClientSession; + Client client = clientSession.Client; + if (client == null) + return; + + client.Session.Send(Encoding.UTF8.GetBytes(result), EnumMessageId.S2C_UPDATE_UniqueKey); + } + } +} diff --git a/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Packet/PacketManager.cs b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Packet/PacketManager.cs new file mode 100644 index 0000000..7f60379 --- /dev/null +++ b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Packet/PacketManager.cs @@ -0,0 +1,73 @@ +using SystemX.Core.Communication; + +namespace WebApi.Project.UniqueKeyApi.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, ushort> 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); + + _onRecv.Add((ushort)EnumMessageId.C2S_SELECT_UniqueKey, MakePacket); + _handler.Add((ushort)EnumMessageId.C2S_SELECT_UniqueKey, PacketHandler.C2S_SELECT_UniqueKeyHandler); + + _onRecv.Add((ushort)EnumMessageId.C2S_UPDATE_UniqueKey, MakePacket); + _handler.Add((ushort)EnumMessageId.C2S_UPDATE_UniqueKey, PacketHandler.C2S_UPDATE_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; + + ushort packetSize = (ushort)(buffer.Count - count); + byte[] packet = new byte[packetSize]; + Array.Copy(buffer.ToArray(), count, packet, 0, packetSize); + + if (_onRecv.TryGetValue(id, out var action)) + action.Invoke(session, packet, id); + } + + void MakePacket(PacketSession session, ArraySegment buffer, ushort id) where T : new() + { + if (CustomHandler != null) + { + CustomHandler.Invoke(session, buffer, id); + } + else + { + Action> action = null; + if (_handler.TryGetValue(id, out action)) + action.Invoke(session, buffer); + } + } + + public Action> GetPacketHandler(ushort id) + { + Action> action = null; + if (_handler.TryGetValue(id, out action)) + return action; + return null; + } + } +} diff --git a/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Packet/Protocol.cs b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Packet/Protocol.cs new file mode 100644 index 0000000..436aae8 --- /dev/null +++ b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Packet/Protocol.cs @@ -0,0 +1,38 @@ +namespace WebApi.Project.UniqueKeyApi.Socket.Packet +{ + public interface IMessage + { + } + + public class C2S : IMessage + { + // public EnumMessageId MessageId { 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 C2S_SELECT_UniqueKey : C2S + { + public string Identity { get; set; } + } + + public sealed class C2S_UPDATE_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; } + } +} diff --git a/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Session/ClientSession.cs b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Session/ClientSession.cs new file mode 100644 index 0000000..3f9cb0e --- /dev/null +++ b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Session/ClientSession.cs @@ -0,0 +1,51 @@ +using System.Net; +using System.Text; +using SystemX.Core.Communication; +using WebApi.Project.UniqueKeyApi.Socket.Object; +using WebApi.Project.UniqueKeyApi.Socket.Packet; + +namespace WebApi.Project.UniqueKeyApi.Socket.Session +{ + public class ClientSession : PacketSession + { + public Client Client { get; set; } + public int SessionId { get; set; } + + public void Send(ArraySegment packet, EnumMessageId resonseMessageId) + { + LogXnet.WriteLine($"Send:{Encoding.UTF8.GetString(packet)}", LogXLabel.SOCKET); + + ushort size = (ushort)packet.Count; + byte[] sendBuffer = new byte[size + 4]; + Array.Copy(BitConverter.GetBytes((ushort)(size + 4)), 0, sendBuffer, 0, sizeof(ushort)); + Array.Copy(BitConverter.GetBytes((ushort)resonseMessageId), 0, sendBuffer, 2, sizeof(ushort)); + Array.Copy(packet.ToArray(), 0, sendBuffer, 4, size); + Send(new ArraySegment(sendBuffer)); + } + + public override void OnConnected(EndPoint endPoint) + { + LogXnet.WriteLine($"OnConnected:{endPoint}", LogXLabel.SOCKET); + Client = ObjectManager.Instance.Add(); + { + Client.Session = this; + } + } + + public override void OnRecvPacket(ArraySegment buffer) + { + LogXnet.WriteLine($"OnRecvPacket:{Encoding.UTF8.GetString(buffer)}", LogXLabel.SOCKET); + PacketManager.Instance.OnRecvPacket(this, buffer); + } + + public override void OnDisconnected(EndPoint endPoint) + { + LogXnet.WriteLine($"OnDisconnected:{endPoint}", LogXLabel.SOCKET); + } + + public override void OnSend(int numOfBytes) + { + //Console.WriteLine($"Transferred bytes: {numOfBytes}"); + } + } +} diff --git a/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Session/SessionManager.cs b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Session/SessionManager.cs new file mode 100644 index 0000000..a0c1aa2 --- /dev/null +++ b/Projects/WebApi/WebApi.Project.UniqueKeyApi/Socket/Session/SessionManager.cs @@ -0,0 +1,46 @@ +namespace WebApi.Project.UniqueKeyApi.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); + + LogXnet.WriteLine($"Connected : {sessionId}", LogXLabel.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/WebApi/WebApi.Project.UniqueKeyApi/TaskManager/TaskSocket.cs b/Projects/WebApi/WebApi.Project.UniqueKeyApi/TaskManager/TaskSocket.cs index ee3e449..e568478 100644 --- a/Projects/WebApi/WebApi.Project.UniqueKeyApi/TaskManager/TaskSocket.cs +++ b/Projects/WebApi/WebApi.Project.UniqueKeyApi/TaskManager/TaskSocket.cs @@ -1,28 +1,29 @@ using System.Net; using SystemX.Core.Communication; +using WebApi.Project.UniqueKeyApi.Socket.Session; namespace WebApi.Project.UniqueKeyApi.TaskManager { public class TaskSocket { - //public async Task Run(int socketPort = 7777) - //{ - // try - // { - // await Task.Delay(1000); - // Listener _listener = new Listener(); - // IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, socketPort); + public async Task Run(int socketPort = 7777) + { + try + { + await Task.Delay(1000); + Listener _listener = new Listener(); + IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, socketPort); - // _listener.Init(endPoint, () => { return SessionManager.Instance.Generate(); }); + _listener.Init(endPoint, () => { return SessionManager.Instance.Generate(); }); - // Log4net.WriteLine($"Address:{endPoint.Address}, Port:{socketPort}", LogType.SOCKET); - // Log4net.WriteLine($"Socket Listening Start", LogType.SOCKET); - // } - // catch (Exception e) - // { - // Log4net.WriteLine("Socket Run Failed", LogType.Error); - // Log4net.WriteLine(e); - // } - //} + LogXnet.WriteLine($"Address:{endPoint.Address}, Port:{socketPort}", LogXLabel.SOCKET); + LogXnet.WriteLine($"Socket Listening Start", LogXLabel.SOCKET); + } + catch (Exception e) + { + LogXnet.WriteLine("Socket Run Failed", LogXLabel.Error); + LogXnet.WriteLine(e); + } + } } }