From 126131b842efbc9e372663106425d11b32143a15 Mon Sep 17 00:00:00 2001 From: CortexCore <2630229280@qq.com> Date: Wed, 12 Jun 2024 16:01:56 +0800 Subject: [PATCH] 1 --- Src/Core/Binary/BITBinary.cs | 132 +++++++++--------- Src/Core/Kcp/KcpNetClient.cs | 53 +++++-- Src/Core/Kcp/KcpNetServer.cs | 90 +++++++++--- Src/Core/Mathematics/MathO.cs | 19 ++- Src/Core/Net/NetProvider.cs | 4 +- .../Scripts/NetProvider/GameNetProvider.cs | 4 +- .../Scripts/NetProvider/Kcp/MonoKcpClient.cs | 10 +- .../Scripts/NetProvider/Kcp/MonoKcpServer.cs | 8 +- 8 files changed, 208 insertions(+), 112 deletions(-) diff --git a/Src/Core/Binary/BITBinary.cs b/Src/Core/Binary/BITBinary.cs index e973f54..0a4eb3d 100644 --- a/Src/Core/Binary/BITBinary.cs +++ b/Src/Core/Binary/BITBinary.cs @@ -61,51 +61,53 @@ namespace BITKit public static object Read(BinaryReader reader) { - try + if (reader.ReadBoolean()) { - if (reader.ReadBoolean()) + var objs = new object[reader.ReadInt32()]; + for (var i = 0; i < objs.Length; i++) { - var objs = new object[reader.ReadInt32()]; - for (var i = 0; i < objs.Length; i++) - { - objs[i] = Read(reader); - } - return objs.ToArray(); + objs[i] = ReadInternel(reader); } - } - catch (Exception) - { - - } - - var typeName = reader.ReadString(); - if (netReaders.TryGetValue(typeName, out var netReader)) - return netReader.ReadBinaryAsObject(reader); - - var instance = System.Activator.CreateInstance(BITSharp.GetTypeFromFullName(typeName)); - if (instance is IBinarySerialize serialize) - { - serialize.Read(reader); - return instance; + return objs.ToArray(); } - - var json = reader.ReadString(); - if (string.IsNullOrEmpty(json)) + + return ReadInternel(reader); + + object ReadInternel(BinaryReader reader) { - throw new Exception($"从二进制中读取的json值为空"); + var typeName = reader.ReadString(); + + + if (netReaders.TryGetValue(typeName, out var netReader)) + return netReader.ReadBinaryAsObject(reader); + + var instance = System.Activator.CreateInstance(BITSharp.GetTypeFromFullName(typeName)); + if (instance is IBinarySerialize serialize) + { + serialize.Read(reader); + return instance; + } + + var json = reader.ReadString(); + if (string.IsNullOrEmpty(json)) + { + throw new Exception($"从二进制中读取的json值为空"); + } + + try + { + if (BITSharp.TryGetTypeFromFullName(typeName, out var type)) + return JsonConvert.DeserializeObject(json, type); + } + catch (Exception e) + { + BIT4Log.Warning($"反序列化失败,类型:{typeName},值:\n{json}"); + BIT4Log.LogException(e); + } + + throw new Exception("未找到读取该二进制的BinaryReader"); } - try - { - if (BITSharp.TryGetTypeFromFullName(typeName, out var type)) - return JsonConvert.DeserializeObject(json, type); - } - catch (Exception e) - { - BIT4Log.Warning($"反序列化失败,类型:{typeName},值:\n{json}"); - BIT4Log.LogException(e); - } - throw new Exception("未找到读取该二进制的BinaryReader"); } public static byte[] WriteAsBytes(object value) @@ -119,47 +121,45 @@ namespace BITKit { if (value is object[] objects) { - if (objects.Length is 1) + writer.Write(true); + writer.Write(objects.Length); + foreach (var obj in objects) { - writer.Write(false); - value = objects[0]; - } - else - { - writer.Write(true); - writer.Write(objects.Length); - foreach (var obj in objects) - { - Write(writer,obj); - } + WriteInterel(writer, obj); } } else { writer.Write(false); + WriteInterel(writer,value); } - var typeName = value.GetType().FullName; - writer.Write(typeName!); - if (netReaders.TryGetValue(typeName, out var netReader)) + return; + void WriteInterel(BinaryWriter writer, object value) { - netReader.WriteBinaryAsObject(writer,value); - } - else if (value is IBinarySerialize serialize) - { - serialize.Write(writer); - } - else - { - try + var typeName = value.GetType().FullName; + writer.Write(typeName!); + if (netReaders.TryGetValue(typeName, out var netReader)) { - writer.Write(JsonConvert.SerializeObject(value)); + netReader.WriteBinaryAsObject(writer,value); } - catch (Exception e) + else if (value is IBinarySerialize serialize) { - BIT4Log.Warning(typeName); - throw; + serialize.Write(writer); } + else + { + try + { + writer.Write(JsonConvert.SerializeObject(value)); + } + catch (Exception e) + { + BIT4Log.Warning(typeName); + throw; + } + } + } } public static bool IsSupport(object obj) => IsSupport(obj.GetType().FullName); diff --git a/Src/Core/Kcp/KcpNetClient.cs b/Src/Core/Kcp/KcpNetClient.cs index 42ea7e5..e012251 100644 --- a/Src/Core/Kcp/KcpNetClient.cs +++ b/Src/Core/Kcp/KcpNetClient.cs @@ -8,6 +8,7 @@ using Timer = System.Timers.Timer; using System.Threading.Tasks; using System.IO; using System.Numerics; +using System.Reflection; using BITKit.Net.Examples; using Newtonsoft.Json; @@ -43,6 +44,9 @@ namespace BITKit.Net private int _index = int.MinValue; private readonly ConcurrentDictionary _p2p = new(); private readonly ConcurrentDictionary>> _rpc = new(); + private readonly ConcurrentDictionary _rpcMethods = new(); + private readonly ConcurrentDictionary _rpcHandles = new(); + public KcpNetClient() { client = new KcpClient( @@ -124,7 +128,18 @@ namespace BITKit.Net } } - private async void OnData(ArraySegment bytes, KcpChannel channel) + private void OnData(ArraySegment bytes, KcpChannel channel) + { + try + { + OnDataInternel(bytes, channel); + } + catch (Exception e) + { + BIT4Log.LogException(e); + } + } + private async void OnDataInternel(ArraySegment bytes, KcpChannel channel) { using var ms = new MemoryStream(bytes.ToArray()); using var reader = new BinaryReader(ms); @@ -191,19 +206,28 @@ namespace BITKit.Net try { var requestId = reader.ReadInt32(); - var commandObj = BITBinary.Read(reader); - - if (_rpc.TryGetValue(commandObj.GetType().FullName, out var func) is false) - { - throw new NotImplementedException($"未找到对应的方法:{commandObj.GetType().FullName}"); - } + + using var _ms = new MemoryStream(); using var _writer = new BinaryWriter(_ms); _writer.Write((byte)NetCommandType.ReturnToServer); _writer.Write(requestId); try { - var value = await func.As>>().Invoke(commandObj); + object value = null; + if (reader.ReadBoolean()) + { + var path = reader.ReadString(); + var method = _rpcMethods[path]; + var pars = BITBinary.Read(reader).As(); + value = method.Invoke(_rpcHandles[path],pars); + } + else + { + var commandObj = BITBinary.Read(reader); + var func = _rpc[commandObj.GetType()!.FullName!]; + value = await func.As>>().Invoke(commandObj); + } _writer.Write(true); BITBinary.Write(_writer, value); @@ -278,13 +302,22 @@ namespace BITKit.Net Send(NetCommandType.TargetCommand,id,command); } - public async UniTask GetFromServer(T command = default) + public async UniTask GetFromServer(string path = default,T command = default) { var id = _index++; using var ms = new MemoryStream(); await using var writer = new BinaryWriter(ms); writer.Write((byte)NetCommandType.GetFromServer); writer.Write(id); + if (string.IsNullOrEmpty(path)) + { + writer.Write(false); + } + else + { + writer.Write(true); + writer.Write(path); + } BITBinary.Write(writer,command); var bytes = ms.ToArray(); @@ -307,7 +340,7 @@ namespace BITKit.Net } } - public UniTask GetFromClient(int id, T command = default) + public UniTask GetFromClient(int id,string path, T command = default) { throw new NotImplementedException(); } diff --git a/Src/Core/Kcp/KcpNetServer.cs b/Src/Core/Kcp/KcpNetServer.cs index 7bf77cb..78150ca 100644 --- a/Src/Core/Kcp/KcpNetServer.cs +++ b/Src/Core/Kcp/KcpNetServer.cs @@ -10,6 +10,7 @@ using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; +using System.Reflection; using System.Threading.Tasks; using BITKit.Net.Examples; @@ -32,7 +33,8 @@ namespace BITKit.Net private int _index = 1001; private readonly ConcurrentDictionary _p2p = new(); private readonly ConcurrentDictionary>> _rpc = new(); - + private readonly ConcurrentDictionary _rpcMethods = new(); + private readonly ConcurrentDictionary _rpcHandles = new(); public KCPNetServer() { @@ -148,7 +150,19 @@ namespace BITKit.Net OnClientDisconnected?.Invoke(Id); BIT4Log.Log($"{Id}已断开"); } - private async void OnData(int Id, ArraySegment bytes, KcpChannel channel) + + private void OnData(int Id, ArraySegment bytes, KcpChannel channel) + { + try + { + OnDataInternel(Id, bytes, channel); + } + catch (Exception e) + { + BIT4Log.LogException(e); + } + } + private async void OnDataInternel(int Id, ArraySegment bytes, KcpChannel channel) { using var ms = new MemoryStream(bytes.ToArray()); using var reader = new BinaryReader(ms); @@ -191,37 +205,60 @@ namespace BITKit.Net case NetCommandType.GetFromServer: { var requestId = reader.ReadInt32(); - var commandObj = BITBinary.Read(reader); + - using var _ms = new MemoryStream(); - using var _writer = new BinaryWriter(_ms); - _writer.Write((byte)NetCommandType.ReturnToClient); - _writer.Write(requestId); + using var returnMS = new MemoryStream(); + using var returnWriter = new BinaryWriter(returnMS); + returnWriter.Write((byte)NetCommandType.ReturnToClient); + returnWriter.Write(requestId); try { - if (_rpc.TryGetValue(commandObj.GetType()!.FullName!, out var func) is false) + if (reader.ReadBoolean()) { - _writer.Write(false); - _writer.Write("未找到对应的Rpc方法"); + var path = reader.ReadString(); + var pars = BITBinary.Read(reader).As(); + if (_rpcMethods.TryGetValue(path, out var methodInfo)) + { + var value = methodInfo.Invoke(_rpcHandles[path], pars); + returnWriter.Write(true); + BITBinary.Write(returnWriter, value); + } + else + { + returnWriter.Write(false); + returnWriter.Write("未找到对应的Rpc方法"); + } + } else { - try + var commandObj = BITBinary.Read(reader); + if (_rpc.TryGetValue(commandObj.GetType()!.FullName!, out var func)) { - var value = await func.As>>().Invoke(commandObj); - _writer.Write(true); - BITBinary.Write(_writer, value); + try + { + var value = await func.As>>().Invoke(commandObj); + returnWriter.Write(true); + BITBinary.Write(returnWriter, value); + } + catch (Exception e) + { + BIT4Log.LogException(e); + returnWriter.Write(false); + returnWriter.Write(e.Message); + } } - catch (Exception e) + else { - BIT4Log.LogException(e); - _writer.Write(false); - _writer.Write(e.Message); + returnWriter.Write(false); + returnWriter.Write("未找到对应的Rpc方法"); } } - var _bytes = _ms.ToArray(); - server.Send(Id, _bytes, KcpChannel.Reliable); + { + var _bytes = returnMS.ToArray(); + server.Send(Id, _bytes, KcpChannel.Reliable); + } } catch (Exception e) { @@ -273,18 +310,27 @@ namespace BITKit.Net Send(id,NetCommandType.Command,command); } - public UniTask GetFromServer(T command = default) + public UniTask GetFromServer(string path=default,T command = default) { throw new NotImplementedException(); } - public async UniTask GetFromClient(int id, T command = default) + public async UniTask GetFromClient(int id,string path=default, T command = default) { var index = _index++; using var ms = new MemoryStream(); await using var writer = new BinaryWriter(ms); writer.Write((byte)NetCommandType.GetFromClient); writer.Write(index); + if (string.IsNullOrEmpty(path)) + { + writer.Write(false); + } + else + { + writer.Write(true); + writer.Write(path); + } BITBinary.Write(writer,command); var bytes = ms.ToArray(); diff --git a/Src/Core/Mathematics/MathO.cs b/Src/Core/Mathematics/MathO.cs index 9d1bbc0..e183470 100644 --- a/Src/Core/Mathematics/MathO.cs +++ b/Src/Core/Mathematics/MathO.cs @@ -4,6 +4,23 @@ namespace BITKit { public static class MathO { - public static T As(this object self) where T : class => self as T; + public static T As(this object self) where T : class + { + { + if (typeof(T) == typeof(object[])) + { + var o = new object[1]; + o[0] = self; + return o as T; + } + } + { + if (self is object[] { Length: 1 } o) + { + return o[0] as T; + } + } + return self as T; + } } } \ No newline at end of file diff --git a/Src/Core/Net/NetProvider.cs b/Src/Core/Net/NetProvider.cs index beaf0a4..8f31460 100644 --- a/Src/Core/Net/NetProvider.cs +++ b/Src/Core/Net/NetProvider.cs @@ -74,7 +74,7 @@ namespace BITKit /// /// /// - UniTask GetFromServer(T command = default); + UniTask GetFromServer(string path = null,T command = default); /// /// 从客户端获取数据 @@ -83,7 +83,7 @@ namespace BITKit /// 可寻址路劲 e.g. Key /// 远程指令类型 /// - UniTask GetFromClient(int id,T command = default); + UniTask GetFromClient(int id,string path = null,T command = default); /// /// 添加RPC远程服务,服务类型为需要的方法标记[RPC] diff --git a/Src/Unity/Scripts/NetProvider/GameNetProvider.cs b/Src/Unity/Scripts/NetProvider/GameNetProvider.cs index a3a1d80..20b0d0e 100644 --- a/Src/Unity/Scripts/NetProvider/GameNetProvider.cs +++ b/Src/Unity/Scripts/NetProvider/GameNetProvider.cs @@ -89,9 +89,9 @@ namespace BITKit.Net _netProviderImplementation.ClientCommand(id, command); } - public UniTask GetFromServer(T command = default)=>_netProviderImplementation.GetFromServer(command); + public UniTask GetFromServer(string path=default,T command = default)=>_netProviderImplementation.GetFromServer(path,command); - public UniTask GetFromClient(int id, T command = default)=>_netProviderImplementation.GetFromClient(id, command); + public UniTask GetFromClient(int id,string path=default, T command = default)=>_netProviderImplementation.GetFromClient(id,path, command); public void AddRpcHandle(object rpcHandle) { diff --git a/Src/Unity/Scripts/NetProvider/Kcp/MonoKcpClient.cs b/Src/Unity/Scripts/NetProvider/Kcp/MonoKcpClient.cs index 01497f8..0cc4107 100644 --- a/Src/Unity/Scripts/NetProvider/Kcp/MonoKcpClient.cs +++ b/Src/Unity/Scripts/NetProvider/Kcp/MonoKcpClient.cs @@ -96,14 +96,14 @@ namespace BITKit.Net.Kcp _netProviderImplementation.ClientCommand(id, command); } - public UniTask GetFromServer(T command = default) + public UniTask GetFromServer(string path=null,T command = default) { - return _netProviderImplementation.GetFromServer(command); + return _netProviderImplementation.GetFromServer(path,command); } - public UniTask GetFromClient(int id, T command = default) + public UniTask GetFromClient(int id,string path=null, T command = default) { - return _netProviderImplementation.GetFromClient(id, command); + return _netProviderImplementation.GetFromClient(id,path, command); } public void AddRpcHandle(object rpcHandle) { @@ -227,7 +227,7 @@ namespace BITKit.Net.Kcp private async void Hello() { BITAppForUnity.ThrowIfNotPlaying(); - var value =await GetFromServer(new SimplePing() + var value =await GetFromServer(null,new SimplePing() { StartTime = DateTime.Now }); diff --git a/Src/Unity/Scripts/NetProvider/Kcp/MonoKcpServer.cs b/Src/Unity/Scripts/NetProvider/Kcp/MonoKcpServer.cs index 695b49b..9379bfc 100644 --- a/Src/Unity/Scripts/NetProvider/Kcp/MonoKcpServer.cs +++ b/Src/Unity/Scripts/NetProvider/Kcp/MonoKcpServer.cs @@ -113,14 +113,14 @@ namespace BITKit.Net.Kcp _server.ClientCommand(id, command); } - public UniTask GetFromServer(T command = default) + public UniTask GetFromServer(string path = null,T command = default) { - return _serverInstance.GetFromServer(command); + return _serverInstance.GetFromServer(path,command); } - public UniTask GetFromClient(int id, T command = default) + public UniTask GetFromClient(int id,string path = null, T command = default) { - return _serverInstance.GetFromClient(id, command); + return _serverInstance.GetFromClient(id,path, command); } public void AddRpcHandle(object rpcHandle) {