This commit is contained in:
CortexCore 2024-08-06 10:27:59 +08:00
parent cc3d6f0ef1
commit d5c21759b5
6 changed files with 412 additions and 84 deletions

View File

@ -55,6 +55,7 @@ namespace BITKit.Net
private readonly ConcurrentDictionary<int, object> _p2p = new(); private readonly ConcurrentDictionary<int, object> _p2p = new();
private readonly ConcurrentDictionary<string,Func<object,UniTask<object>>> _rpc = new(); private readonly ConcurrentDictionary<string,Func<object,UniTask<object>>> _rpc = new();
private readonly ConcurrentDictionary<string,MethodInfo> _rpcMethods = new(); private readonly ConcurrentDictionary<string,MethodInfo> _rpcMethods = new();
private readonly ConcurrentDictionary<string,EventInfo> _rpcEvents = new();
private readonly ConcurrentDictionary<string,object> _rpcHandles = new(); private readonly ConcurrentDictionary<string,object> _rpcHandles = new();
private DateTime _lastHeartbeat = DateTime.Now; private DateTime _lastHeartbeat = DateTime.Now;
private DateTime _now = DateTime.Now; private DateTime _now = DateTime.Now;
@ -291,7 +292,7 @@ namespace BITKit.Net
{ {
var path = reader.ReadString(); var path = reader.ReadString();
var pars = BITBinary.Read(reader).As<object[]>(); var pars = BITBinary.Read(reader).As<object[]>();
if (_rpcMethods.TryGetValue(path, out var methodInfo)) if (_rpcMethods.TryGetValue(path, out var methodInfo))
{ {
@ -321,6 +322,18 @@ namespace BITKit.Net
returnWriter.Write(true); returnWriter.Write(true);
BITBinary.Write(returnWriter, value); BITBinary.Write(returnWriter, value);
} }
else if (_rpcEvents.TryGetValue(path, out var eventInfo))
{
var handle = _rpcHandles[path];
var fieldInfo = handle.GetType().GetField(eventInfo.Name,ReflectionHelper.Flags)!;
var eventDelegate = fieldInfo.GetValue(handle) as MulticastDelegate;
foreach (var del in eventDelegate!.GetInvocationList())
{
del.Method.Invoke(del.Target, pars);
}
}
else else
{ {
returnWriter.Write(false); returnWriter.Write(false);
@ -358,9 +371,9 @@ namespace BITKit.Net
case NetCommandType.TargetRpc: case NetCommandType.TargetRpc:
{ {
var rpcName = reader.ReadString(); var rpcName = reader.ReadString();
var pars = BITBinary.Read(reader).As<object[]>();
if (_rpcMethods.TryGetValue(rpcName, out var methodInfo)) if (_rpcMethods.TryGetValue(rpcName, out var methodInfo))
{ {
var pars = BITBinary.Read(reader).As<object[]>();
try try
{ {
methodInfo.Invoke(_rpcHandles[rpcName], pars); methodInfo.Invoke(_rpcHandles[rpcName], pars);
@ -402,6 +415,18 @@ namespace BITKit.Net
} }
} }
else if (_rpcEvents.TryGetValue(rpcName, out var eventInfo))
{
var handle = _rpcHandles[rpcName];
var fieldInfo = handle.GetType().GetField(eventInfo.Name,ReflectionHelper.Flags)!;
var eventDelegate = fieldInfo.GetValue(handle) as MulticastDelegate;
foreach (var del in eventDelegate!.GetInvocationList())
{
del.Method.Invoke(del.Target, pars);
}
}
else else
{ {
@ -436,7 +461,7 @@ namespace BITKit.Net
{ {
BIT4Log.Log<KcpNetClient>($"{client.remoteEndPoint}异常:{errorCode},{message}"); BIT4Log.Log<KcpNetClient>($"{client.remoteEndPoint}异常:{errorCode},{message}");
} }
public void ServerCommand<T>(T command = default) public void ServerCommand<T>(T command = default)
{ {
using var ms = new MemoryStream(); using var ms = new MemoryStream();
@ -547,20 +572,15 @@ namespace BITKit.Net
reportBuilder.AppendLine($"Add [{methodInfo.Name}] as MethodInfo"); reportBuilder.AppendLine($"Add [{methodInfo.Name}] as MethodInfo");
} }
foreach (var eventInfo in rpcHandle.GetType().GetEvents()) foreach (var eventInfo in rpcHandle.GetType().GetEvents())
{ {
var att = eventInfo.GetCustomAttribute<NetRpcAttribute>(); var att = eventInfo.GetCustomAttribute<NetRpcAttribute>();
if(att is null)continue; if(att is null)continue;
_rpcEvents.TryAdd(eventInfo.Name, eventInfo);
_rpcHandles.TryAdd(eventInfo.Name, rpcHandle);
// var handle = eventInfo.EventHandlerType.GetMethod("Invoke"); reportBuilder.AppendLine($"Add [{eventInfo.Name}] as EventInfo");
var handle = eventInfo.GetAddMethod();
_rpcMethods.AddOrUpdate(eventInfo.Name, handle, (s, info) => handle);
_rpcHandles.AddOrUpdate(eventInfo.Name, rpcHandle, (s, info) => rpcHandle);
reportBuilder.AppendLine($"Add [{eventInfo.Name} as EventInfo]");
} }
BIT4Log.Log<KcpNetClient>(reportBuilder); BIT4Log.Log<KcpNetClient>(reportBuilder);
@ -596,7 +616,9 @@ namespace BITKit.Net
{ {
using var ms = new MemoryStream(); using var ms = new MemoryStream();
using var writer = new BinaryWriter(ms); using var writer = new BinaryWriter(ms);
writer.Write((byte)NetCommandType.GetFromClient); writer.Write((byte)NetCommandType.GetFromServer);
writer.Write(++_index);
writer.Write(true);
writer.Write(rpcName); writer.Write(rpcName);
BITBinary.Write(writer,pars); BITBinary.Write(writer,pars);
var bytes = ms.ToArray(); var bytes = ms.ToArray();

View File

@ -37,6 +37,7 @@ namespace BITKit.Net
private readonly ConcurrentDictionary<int, object> _p2p = new(); private readonly ConcurrentDictionary<int, object> _p2p = new();
private readonly ConcurrentDictionary<string,Func<object,UniTask<object>>> _rpc = new(); private readonly ConcurrentDictionary<string,Func<object,UniTask<object>>> _rpc = new();
private readonly ConcurrentDictionary<string,MethodInfo> _rpcMethods = new(); private readonly ConcurrentDictionary<string,MethodInfo> _rpcMethods = new();
private readonly ConcurrentDictionary<string,EventInfo> _rpcEvents = new();
private readonly ConcurrentDictionary<string,object> _rpcHandles = new(); private readonly ConcurrentDictionary<string,object> _rpcHandles = new();
private readonly ConcurrentDictionary<int,DateTime> _lastHeartbeat = new(); private readonly ConcurrentDictionary<int,DateTime> _lastHeartbeat = new();
@ -48,6 +49,8 @@ namespace BITKit.Net
private readonly byte[] _heartBeat = new byte[] { (byte)NetCommandType.Heartbeat }; private readonly byte[] _heartBeat = new byte[] { (byte)NetCommandType.Heartbeat };
[NetRpc]
public event Action<int, float, bool> OnNetRpcTest;
public KCPNetServer() public KCPNetServer()
{ {
server = new KcpServer( server = new KcpServer(
@ -63,6 +66,12 @@ namespace BITKit.Net
AddCommandListener<SimplePing>(F); AddCommandListener<SimplePing>(F);
AddRpcHandle(this); AddRpcHandle(this);
OnNetRpcTest += (_int, _float, _bool) =>
{
BIT4Log.Log<KCPNetServer>($"已收到Rpc测试:{_int},{_float},{_bool}");
};
return; return;
UniTask<SimplePing> F(SimplePing p) UniTask<SimplePing> F(SimplePing p)
{ {
@ -307,13 +316,13 @@ namespace BITKit.Net
{ {
var path = reader.ReadString(); var path = reader.ReadString();
var pars = BITBinary.Read(reader).As<object[]>(); var pars = BITBinary.Read(reader).As<object[]>();
object value = null;
if (_rpcMethods.TryGetValue(path, out var methodInfo)) if (_rpcMethods.TryGetValue(path, out var methodInfo))
{ {
var isAwaitable = methodInfo.ReturnType.GetMethod(nameof(Task.GetAwaiter)) != null; var isAwaitable = methodInfo.ReturnType.GetMethod(nameof(Task.GetAwaiter)) != null;
var handle = _rpcHandles[path]; var handle = _rpcHandles[path];
object value = null;
if (methodInfo.GetParameters().Length is 0) if (methodInfo.GetParameters().Length is 0)
{ {
pars = new object[] { }; pars = new object[] { };
@ -365,27 +374,38 @@ namespace BITKit.Net
return; return;
} }
returnWriter.Write(true); returnWriter.Write(true);
if (value is not null)
}else if (_rpcEvents.TryGetValue(path, out var eventInfo))
{
var handle = _rpcHandles[path];
var fieldInfo = handle.GetType().GetField(eventInfo.Name,ReflectionHelper.Flags)!;
var eventDelegate = fieldInfo.GetValue(handle) as MulticastDelegate;
foreach (var del in eventDelegate!.GetInvocationList())
{ {
try del.Method.Invoke(del.Target, pars);
{
BITBinary.Write(returnWriter, value);
}
catch (NullReferenceException e)
{
throw;
}
catch (Exception e)
{
throw;
}
} }
} }
else else
{ {
throw new Exception($"未找到对应的Rpc方法:{path}"); throw new Exception($"未找到对应的Rpc方法:{path}");
} }
if (value is not null)
{
try
{
BITBinary.Write(returnWriter, value);
}
catch (NullReferenceException e)
{
throw;
}
catch (Exception e)
{
throw;
}
}
} }
else else
{ {
@ -542,9 +562,9 @@ namespace BITKit.Net
{ {
var att = eventInfo.GetCustomAttribute<NetRpcAttribute>(); var att = eventInfo.GetCustomAttribute<NetRpcAttribute>();
if(att is null)continue; if(att is null)continue;
var handle = eventInfo.EventHandlerType.GetMethod("Invoke");
_rpcMethods.AddOrUpdate(eventInfo.Name, handle, (s, info) => handle); _rpcEvents.TryAdd(eventInfo.Name, eventInfo);
_rpcHandles.AddOrUpdate(eventInfo.Name, rpcHandle, (s, info) => rpcHandle); _rpcHandles.TryAdd(eventInfo.Name, rpcHandle);
} }
} }

File diff suppressed because one or more lines are too long

View File

@ -78,6 +78,8 @@ namespace BITKit
private IReference getLatestUrl; private IReference getLatestUrl;
[SerializeField, SerializeReference, SubclassSelector] [SerializeField, SerializeReference, SubclassSelector]
private WebProvider webProvider; private WebProvider webProvider;
[SerializeReference, SubclassSelector] private ITicker checkTick;
[SerializeField] private bool dontDestroyOnLoad; [SerializeField] private bool dontDestroyOnLoad;
event Action<string> IApplicationService.OnClientVersionCheck event Action<string> IApplicationService.OnClientVersionCheck
@ -114,8 +116,6 @@ namespace BITKit
private UnityWebRequest downloadRequest; private UnityWebRequest downloadRequest;
private CancellationTokenSource _cancellationTokenSource;
public async UniTask<string> DownloadLatestVersionAsync() public async UniTask<string> DownloadLatestVersionAsync()
{ {
var filePath = var filePath =
@ -136,13 +136,11 @@ namespace BITKit
while (downloadRequest.downloadHandler.isDone is false) while (downloadRequest.downloadHandler.isDone is false)
{ {
OnDownloadProgress?.Invoke(downloadRequest.downloadProgress); OnDownloadProgress?.Invoke(downloadRequest.downloadProgress);
_cancellationTokenSource.Token.ThrowIfCancellationRequested(); destroyCancellationToken.ThrowIfCancellationRequested();
await UniTask.NextFrame(); await UniTask.NextFrame();
} }
await File.WriteAllBytesAsync(filePath, downloadRequest.downloadHandler.data,destroyCancellationToken);
await File.WriteAllBytesAsync(filePath, downloadRequest.downloadHandler.data,_cancellationTokenSource.Token);
OnDownloadComplete?.Invoke(filePath); OnDownloadComplete?.Invoke(filePath);
return filePath; return filePath;
@ -150,14 +148,14 @@ namespace BITKit
public string DownloadLatestUrl => getLatestUrl.Value; public string DownloadLatestUrl => getLatestUrl.Value;
public string CheckLatestVersionUrl=>getVersionUrl.Value; public string CheckLatestVersionUrl=>getVersionUrl.Value;
private bool _isBusy;
private void Awake() private void Awake()
{ {
Singleton = this; Singleton = this;
_cancellationTokenSource = new CancellationTokenSource();
} }
private async void Start() private void Start()
{ {
if (dontDestroyOnLoad) if (dontDestroyOnLoad)
{ {
@ -165,27 +163,44 @@ namespace BITKit
} }
try try
{ {
_cancellationTokenSource.Token.ThrowIfCancellationRequested(); OnTick(0);
var latestVersion = await webProvider.GetAsync(getVersionUrl.Get(), _cancellationTokenSource.Token);
var currentVersion = Application.version;
BIT4Log.Log<ApplicationService>(latestVersion != currentVersion
? $"当前版本{currentVersion}不是最新版本{latestVersion},请及时更新"
: $"当前版本{currentVersion}是最新版本");
OnClientVersionCheck?.Invoke(currentVersion);
OnLatestVersionCheck?.Invoke(latestVersion);
} }
catch(OperationCanceledException){} catch(OperationCanceledException){}
catch (Exception e) catch (Exception e)
{ {
BIT4Log.LogException(e); BIT4Log.LogException(e);
} }
}
private void OnDestroy() destroyCancellationToken.Register(Dispose);
checkTick?.Add(OnTick);
}
private async void OnTick(float deltaTime)
{ {
if(_isBusy)return;
try
{
var latestVersion = await webProvider.GetAsync(getVersionUrl.Get(), destroyCancellationToken);
if (destroyCancellationToken.IsCancellationRequested) return;
var currentVersion = Application.version;
OnClientVersionCheck?.Invoke(currentVersion);
OnLatestVersionCheck?.Invoke(latestVersion);
}
catch (OperationCanceledException)
{
}
catch (Exception e)
{
BIT4Log.LogException(e);
}
_isBusy = false;
}
private void Dispose()
{
checkTick?.Remove(OnTick);
downloadRequest?.Abort(); downloadRequest?.Abort();
_cancellationTokenSource?.Cancel();
} }
} }

View File

@ -254,6 +254,10 @@ namespace BITKit.Net.Kcp
stopWatch.Stop(); stopWatch.Stop();
BIT4Log.Log<MonoKcpClient>($"已返回\n开始:{value.StartTime}\n结束:{value.EndTime}\n延迟:{stopWatch.ElapsedMilliseconds}ms"); BIT4Log.Log<MonoKcpClient>($"已返回\n开始:{value.StartTime}\n结束:{value.EndTime}\n延迟:{stopWatch.ElapsedMilliseconds}ms");
SendRT(nameof(KCPNetServer.OnNetRpcTest),64,12.8f,true);
stopWatch.Reset(); stopWatch.Reset();
stopWatch.Start(); stopWatch.Start();
var hello = var hello =

View File

@ -81,6 +81,7 @@ namespace BITKit.UX
public static void UnRegister(IUXPanel panel) => UnRegistryQueue.Enqueue(panel); public static void UnRegister(IUXPanel panel) => UnRegistryQueue.Enqueue(panel);
public static void Entry<T>() where T : IUXPanel => EntryQueue.Push(Panels[typeof(T).Name]); public static void Entry<T>() where T : IUXPanel => EntryQueue.Push(Panels[typeof(T).Name]);
public static void EntryByName(string name)=> EntryQueue.Push(Panels[name]);
public static void Return() public static void Return()
{ {