SignalRServer improvements

This commit is contained in:
jozsef.b@aycode.com 2024-06-01 08:28:31 +02:00
parent 7f7a4f6ec1
commit 379ca61166
2 changed files with 70 additions and 42 deletions

View File

@ -153,14 +153,12 @@ namespace TIAMSharedUI.Shared.Components.Grids
SignalRClient.PostDataAsync(messageTag, dataItem, async repsonse =>
{
if (repsonse.Status != SignalResponseStatus.Success || repsonse.ResponseData == null)
if (repsonse.Status != SignalResponseStatus.Success || repsonse.ResponseData == null || !RefreshDataSourceItem(repsonse.ResponseData, isDelete))
{
RefreshDataSourceAsync().Forget();
return;
}
RefreshDataSourceItem(repsonse.ResponseData, isDelete);
await OnDataSourceItemChanged.InvokeAsync(dataItem);
await InvokeAsync(StateHasChanged);
}).Forget();
@ -168,8 +166,14 @@ namespace TIAMSharedUI.Shared.Components.Grids
//transfer = await devAdminSignalClient.PostDataAsync(SignalRTags.UpdateTransferAsync, transfer);
}
public void RefreshDataSourceItem(TDataItem dataItem, bool isDelete, bool invokeItemChanged = true)
public bool RefreshDataSourceItem(TDataItem dataItem, bool isDelete, bool invokeItemChanged = true)
{
if (dataItem.Id.IsNullOrEmpty())
{
Logger.Error($"dataItem.Id.IsNullOrEmpty()");
return false;
}
var transferIndex = _dataSource.FindIndex(x => x.Id == dataItem.Id);
if (isDelete && transferIndex > -1) _dataSource.RemoveAt(transferIndex);
@ -178,6 +182,8 @@ namespace TIAMSharedUI.Shared.Components.Grids
if (transferIndex > -1) _dataSource[transferIndex] = dataItem;
else _dataSource.Add(dataItem);
}
return true;
}
protected override Task SetParametersAsyncCore(ParameterView parameters)

View File

@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using System.Reflection;
using System.Reflection.Emit;
using AyCode.Core.Extensions;
using AyCode.Core.Loggers;
using AyCode.Services.SignalRs;
@ -41,16 +42,45 @@ public enum MethodParamType : byte
}
[AttributeUsage(AttributeTargets.Method)]
public class SignalRAttribute(int messageTag, MethodParamType methodParamType, Type paramType = null) : Attribute
public class TagAttribute(int messageTag) : Attribute
{
public int MessageTag { get; init; } = messageTag;
}
[AttributeUsage(AttributeTargets.Method)]
public class SignalRAttribute(int messageTag, MethodParamType methodParamType, Type paramType = null) : TagAttribute(messageTag)
{
public MethodParamType MethodParamType { get; init; } = methodParamType;
public Type ParamType { get; init; } = paramType;
}
public class MethodInfoModel<TAttribute>(TAttribute attribute, MethodInfo methodInfo) where TAttribute : TagAttribute
{
public TAttribute Attribute { get; set; } = attribute;
public MethodInfo MethodInfo { get; set; } = methodInfo;
}
public class DynamicMethodCallModel<TAttribute> where TAttribute : TagAttribute
{
public object InstanceObject { get; init; }
public ConcurrentDictionary<int, MethodInfoModel<TAttribute>> MethodsByMessageTag { get; init; } = new();
public DynamicMethodCallModel(object instanceObject)
{
InstanceObject = instanceObject;
foreach (var methodInfo in instanceObject.GetType().GetMethods())
{
if (methodInfo.GetCustomAttribute(typeof(TAttribute)) is not TAttribute attribute) continue;
MethodsByMessageTag[attribute.MessageTag] = new MethodInfoModel<TAttribute>(attribute, methodInfo!);
}
}
}
public class DevAdminSignalRHub : Hub<ISignalRHubItemServer>, IAcSignalRHubServer
{
private readonly ConcurrentDictionary<object, ConcurrentDictionary<int, MethodInfo>> _methodsByMessageTag = new();
private readonly List<DynamicMethodCallModel<SignalRAttribute>> _dynamicMethodCallModels = new();
private readonly TIAM.Core.Loggers.Logger<DevAdminSignalRHub> _logger;
private readonly AdminDal _adminDal;
@ -62,25 +92,11 @@ public class DevAdminSignalRHub : Hub<ISignalRHubItemServer>, IAcSignalRHubServe
_adminDal = adminDal;
_serviceProviderApiController = serviceProviderApiController;
_transferDataApiController = transferDataApiController;
_logger = new(logWriters.ToArray());
var methods = typeof(ServiceProviderAPIController).GetMethods().Where(x => x.GetCustomAttributes(typeof(SignalRAttribute), false).Length > 0);
_methodsByMessageTag[serviceProviderApiController] = new();
foreach (var methodInfo in methods)
{
var atr = methodInfo.GetCustomAttribute(typeof(SignalRAttribute)) as SignalRAttribute;
_methodsByMessageTag[serviceProviderApiController][atr.MessageTag] = methodInfo;
}
methods = typeof(TransferDataAPIController).GetMethods().Where(x => x.GetCustomAttributes(typeof(SignalRAttribute), false).Length > 0);
_methodsByMessageTag[transferDataApiController] = new();
foreach (var methodInfo in methods)
{
var atr = methodInfo.GetCustomAttribute(typeof(SignalRAttribute)) as SignalRAttribute;
_methodsByMessageTag[transferDataApiController][atr.MessageTag] = methodInfo;
}
_dynamicMethodCallModels.Add(new DynamicMethodCallModel<SignalRAttribute>(serviceProviderApiController));
_dynamicMethodCallModels.Add(new DynamicMethodCallModel<SignalRAttribute>(transferDataApiController));
}
@ -121,33 +137,39 @@ public class DevAdminSignalRHub : Hub<ISignalRHubItemServer>, IAcSignalRHubServe
try
{
foreach (var methodsByDeclaringObject in _methodsByMessageTag)
foreach (var methodsByDeclaringObject in _dynamicMethodCallModels)
{
if (methodsByDeclaringObject.Value.TryGetValue(messageTag, out var methodInfo))
if (!methodsByDeclaringObject.MethodsByMessageTag.TryGetValue(messageTag, out var methodInfoModel)) continue;
object[]? paramValues = null;
var parameters = methodInfoModel.MethodInfo.GetParameters();
logText = $"Found the dynamic method for the tag! tag: {messageTag}; method: {methodsByDeclaringObject.InstanceObject.GetType().Name}.{methodInfoModel.MethodInfo.Name}";
if (parameters.Length > 0)
{
var atr = methodInfo.GetCustomAttribute(typeof(SignalRAttribute)) as SignalRAttribute;
object[]? param = null;
_logger.Debug($"{logText}({parameters[0].ParameterType.Name})");
if (atr.MethodParamType != MethodParamType.None)
paramValues = new object[1];
if (parameters[0].ParameterType == typeof(Guid) || parameters[0].ParameterType == typeof(Guid?))
{
param = new object[1];
if (atr.MethodParamType == MethodParamType.Id)
{
param[0] = message!.MessagePackTo<SignalRequestByIdMessage>().Id;
}
else
{
var msg = message!.MessagePackTo<SignalPostJsonDataMessage<object>>(MessagePackSerializerOptions.Standard);
param[0] = msg.PostDataJson.JsonTo(atr.ParamType)!;
}
paramValues[0] = message!.MessagePackTo<SignalRequestByIdMessage>().Id;
}
else
{
var msg = message!.MessagePackTo<SignalPostJsonDataMessage<object>>(MessagePackSerializerOptions.Standard);
paramValues[0] = msg.PostDataJson.JsonTo(parameters[0].ParameterType)!;
}
await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, methodInfo.InvokeMethod(methodsByDeclaringObject.Key, param)), requestId);
return;
}
else _logger.Debug($"{logText}()");
await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, methodInfoModel.MethodInfo.InvokeMethod(methodsByDeclaringObject.InstanceObject, paramValues)), requestId);
return;
}
_logger.Debug($"Not found the dynamic method for the tag! tag: {messageTag};");
switch (messageTag)
{
case SignalRTags.RemoveCompanyAsync: