This commit is contained in:
CortexCore 2024-06-12 16:01:56 +08:00
parent 01b19130a9
commit 126131b842
8 changed files with 208 additions and 112 deletions

View File

@ -60,26 +60,25 @@ namespace BITKit
}
public static object Read(BinaryReader reader)
{
try
{
if (reader.ReadBoolean())
{
var objs = new object[reader.ReadInt32()];
for (var i = 0; i < objs.Length; i++)
{
objs[i] = Read(reader);
objs[i] = ReadInternel(reader);
}
return objs.ToArray();
}
}
catch (Exception)
return ReadInternel(reader);
object ReadInternel(BinaryReader reader)
{
}
var typeName = reader.ReadString();
if (netReaders.TryGetValue(typeName, out var netReader))
return netReader.ReadBinaryAsObject(reader);
@ -95,6 +94,7 @@ namespace BITKit
{
throw new Exception($"从二进制中读取的json值为空");
}
try
{
if (BITSharp.TryGetTypeFromFullName(typeName, out var type))
@ -105,8 +105,10 @@ namespace BITKit
BIT4Log.Warning<BITBinary>($"反序列化失败,类型:{typeName},值:\n{json}");
BIT4Log.LogException(e);
}
throw new Exception("未找到读取该二进制的BinaryReader");
}
}
public static byte[] WriteAsBytes(object value)
{
@ -118,26 +120,22 @@ namespace BITKit
public static void Write(BinaryWriter writer, object value)
{
if (value is object[] objects)
{
if (objects.Length is 1)
{
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);
}
return;
void WriteInterel(BinaryWriter writer, object value)
{
var typeName = value.GetType().FullName;
writer.Write(typeName!);
if (netReaders.TryGetValue(typeName, out var netReader))
@ -161,6 +159,8 @@ namespace BITKit
}
}
}
}
public static bool IsSupport(object obj) => IsSupport(obj.GetType().FullName);
public static bool IsSupport(Type type) => IsSupport(type.FullName);

View File

@ -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<int, object> _p2p = new();
private readonly ConcurrentDictionary<string,Func<object,UniTask<object>>> _rpc = new();
private readonly ConcurrentDictionary<string,MethodInfo> _rpcMethods = new();
private readonly ConcurrentDictionary<string,object> _rpcHandles = new();
public KcpNetClient()
{
client = new KcpClient(
@ -124,7 +128,18 @@ namespace BITKit.Net
}
}
private async void OnData(ArraySegment<byte> bytes, KcpChannel channel)
private void OnData(ArraySegment<byte> bytes, KcpChannel channel)
{
try
{
OnDataInternel(bytes, channel);
}
catch (Exception e)
{
BIT4Log.LogException(e);
}
}
private async void OnDataInternel(ArraySegment<byte> 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<Func<object, UniTask<object>>>().Invoke(commandObj);
object value = null;
if (reader.ReadBoolean())
{
var path = reader.ReadString();
var method = _rpcMethods[path];
var pars = BITBinary.Read(reader).As<object[]>();
value = method.Invoke(_rpcHandles[path],pars);
}
else
{
var commandObj = BITBinary.Read(reader);
var func = _rpc[commandObj.GetType()!.FullName!];
value = await func.As<Func<object, UniTask<object>>>().Invoke(commandObj);
}
_writer.Write(true);
BITBinary.Write(_writer, value);
@ -278,13 +302,22 @@ namespace BITKit.Net
Send(NetCommandType.TargetCommand,id,command);
}
public async UniTask<T> GetFromServer<T>(T command = default)
public async UniTask<T> GetFromServer<T>(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<T> GetFromClient<T>(int id, T command = default)
public UniTask<T> GetFromClient<T>(int id,string path, T command = default)
{
throw new NotImplementedException();
}

View File

@ -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<int, object> _p2p = new();
private readonly ConcurrentDictionary<string,Func<object,UniTask<object>>> _rpc = new();
private readonly ConcurrentDictionary<string,MethodInfo> _rpcMethods = new();
private readonly ConcurrentDictionary<string,object> _rpcHandles = new();
public KCPNetServer()
{
@ -148,7 +150,19 @@ namespace BITKit.Net
OnClientDisconnected?.Invoke(Id);
BIT4Log.Log<KCPNetServer>($"{Id}已断开");
}
private async void OnData(int Id, ArraySegment<byte> bytes, KcpChannel channel)
private void OnData(int Id, ArraySegment<byte> bytes, KcpChannel channel)
{
try
{
OnDataInternel(Id, bytes, channel);
}
catch (Exception e)
{
BIT4Log.LogException(e);
}
}
private async void OnDataInternel(int Id, ArraySegment<byte> bytes, KcpChannel channel)
{
using var ms = new MemoryStream(bytes.ToArray());
using var reader = new BinaryReader(ms);
@ -191,38 +205,61 @@ 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<object[]>();
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
{
var commandObj = BITBinary.Read(reader);
if (_rpc.TryGetValue(commandObj.GetType()!.FullName!, out var func))
{
try
{
var value = await func.As<Func<object, UniTask<object>>>().Invoke(commandObj);
_writer.Write(true);
BITBinary.Write(_writer, value);
returnWriter.Write(true);
BITBinary.Write(returnWriter, value);
}
catch (Exception e)
{
BIT4Log.LogException(e);
_writer.Write(false);
_writer.Write(e.Message);
returnWriter.Write(false);
returnWriter.Write(e.Message);
}
}
var _bytes = _ms.ToArray();
else
{
returnWriter.Write(false);
returnWriter.Write("未找到对应的Rpc方法");
}
}
{
var _bytes = returnMS.ToArray();
server.Send(Id, _bytes, KcpChannel.Reliable);
}
}
catch (Exception e)
{
BIT4Log.LogException(e);
@ -273,18 +310,27 @@ namespace BITKit.Net
Send(id,NetCommandType.Command,command);
}
public UniTask<T> GetFromServer<T>(T command = default)
public UniTask<T> GetFromServer<T>(string path=default,T command = default)
{
throw new NotImplementedException();
}
public async UniTask<T> GetFromClient<T>(int id, T command = default)
public async UniTask<T> GetFromClient<T>(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();

View File

@ -4,6 +4,23 @@ namespace BITKit
{
public static class MathO
{
public static T As<T>(this object self) where T : class => self as T;
public static T As<T>(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;
}
}
}

View File

@ -74,7 +74,7 @@ namespace BITKit
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
UniTask<T> GetFromServer<T>(T command = default);
UniTask<T> GetFromServer<T>(string path = null,T command = default);
/// <summary>
/// 从客户端获取数据
@ -83,7 +83,7 @@ namespace BITKit
/// <param name="addressablePath">可寻址路劲 e.g. Key</param>
/// <typeparam name="T">远程指令类型</typeparam>
/// <returns></returns>
UniTask<T> GetFromClient<T>(int id,T command = default);
UniTask<T> GetFromClient<T>(int id,string path = null,T command = default);
/// <summary>
/// 添加RPC远程服务服务类型为需要的方法标记[RPC]

View File

@ -89,9 +89,9 @@ namespace BITKit.Net
_netProviderImplementation.ClientCommand(id, command);
}
public UniTask<T> GetFromServer<T>(T command = default)=>_netProviderImplementation.GetFromServer<T>(command);
public UniTask<T> GetFromServer<T>(string path=default,T command = default)=>_netProviderImplementation.GetFromServer<T>(path,command);
public UniTask<T> GetFromClient<T>(int id, T command = default)=>_netProviderImplementation.GetFromClient(id, command);
public UniTask<T> GetFromClient<T>(int id,string path=default, T command = default)=>_netProviderImplementation.GetFromClient(id,path, command);
public void AddRpcHandle(object rpcHandle)
{

View File

@ -96,14 +96,14 @@ namespace BITKit.Net.Kcp
_netProviderImplementation.ClientCommand(id, command);
}
public UniTask<T> GetFromServer<T>(T command = default)
public UniTask<T> GetFromServer<T>(string path=null,T command = default)
{
return _netProviderImplementation.GetFromServer<T>(command);
return _netProviderImplementation.GetFromServer<T>(path,command);
}
public UniTask<T> GetFromClient<T>(int id, T command = default)
public UniTask<T> GetFromClient<T>(int id,string path=null, T command = default)
{
return _netProviderImplementation.GetFromClient<T>(id, command);
return _netProviderImplementation.GetFromClient<T>(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<SimplePing>(null,new SimplePing()
{
StartTime = DateTime.Now
});

View File

@ -113,14 +113,14 @@ namespace BITKit.Net.Kcp
_server.ClientCommand(id, command);
}
public UniTask<T> GetFromServer<T>(T command = default)
public UniTask<T> GetFromServer<T>(string path = null,T command = default)
{
return _serverInstance.GetFromServer(command);
return _serverInstance.GetFromServer(path,command);
}
public UniTask<T> GetFromClient<T>(int id, T command = default)
public UniTask<T> GetFromClient<T>(int id,string path = null, T command = default)
{
return _serverInstance.GetFromClient(id, command);
return _serverInstance.GetFromClient(id,path, command);
}
public void AddRpcHandle(object rpcHandle)
{