Compare commits

..

36 Commits

Author SHA1 Message Date
Loretta 5671c36091 updates 2024-10-28 14:02:01 +01:00
Loretta 5d120e167e kurva anyád baszd telibe... 2024-10-10 07:41:13 +02:00
Loretta f4dda6e465 improvements, fixes, etc... 2024-08-30 16:29:39 +02:00
Loretta d872382f19 ComboboxItemSelector.razor improvements, fixes, etc... 2024-08-29 18:01:30 +02:00
Loretta 07ea4678e1 Changing UserDataServiceClientBase Http to Signalr in progress... 2024-08-29 16:40:46 +02:00
Loretta 3f15ef9b4c improvements 2024-08-26 16:35:06 +02:00
Loretta c51ed2f246 implement SiteViewModel; improvements, fixes, etc... 2024-08-21 18:28:21 +02:00
Loretta c1c5cce894 Impoelement DriverManageTransfersPageModel; improvements, fixes, etc... 2024-08-19 19:03:03 +02:00
Loretta 5525e73819 .net packages update to 8.0.8; fixes, etc... 2024-08-14 16:05:55 +02:00
Loretta 0585940f83 improvements, fixes, etc... 2024-08-12 13:21:43 +02:00
Loretta 6dfa7621dc .... 2024-08-09 19:03:00 +02:00
Loretta 8cc523f778 json fix 2024-07-18 19:21:19 +02:00
Loretta 8dafa88462 improvements, fixes, etc... 2024-07-18 17:59:49 +02:00
Loretta a1b2987659 Add Revenue to Transfer; improvements, fixes, etc... 2024-07-08 07:31:22 +02:00
Loretta 8312d0b4cf improvements, fixes, etc... 2024-07-07 08:32:14 +02:00
Loretta bf95f669a3 imprvements, fixes, etc... 2024-07-05 15:39:14 +02:00
Loretta 72e4506ea4 improvements, fixes... 2024-07-04 20:03:24 +02:00
Loretta 57425f91c0 Implement UserProductMapping add/update/delete; improvements, fixes, etc... 2024-07-04 18:33:10 +02:00
Loretta ed11051820 improvements, fixes 2024-07-02 15:18:37 +02:00
Loretta bec9e1be14 ContextIds set to object[] ; improvements, fixes, etc.. 2024-07-02 14:47:26 +02:00
Loretta dfa94cd1d9 fixes 2024-07-01 18:32:45 +02:00
Loretta f007ddf664 improvements, fixes, etc... 2024-07-01 18:16:44 +02:00
Loretta 6f7692fcb0 improvements, fixes, etc... 2024-07-01 08:58:15 +02:00
Loretta e80d830632 improvements, fixes, etc... 2024-06-30 07:13:43 +02:00
Loretta 8e0b79e68e EfCore Tracking fix; Implement FilterText to TiamGrid/DataSource; Implement multiple Context[Id]s params to SignalRClient; improvements, fixes, etc... 2024-06-29 22:27:33 +02:00
Loretta 33d21d9caf improvements, fixes, etc... 2024-06-28 16:44:59 +02:00
Loretta 6ca4e79f77 SignalDataSource fix; 2024-06-26 11:43:48 +02:00
Loretta e343513ef3 Devexpress v24.1.3; TransferStatusType filter in progress.... 2024-06-26 07:42:35 +02:00
Loretta 2f3abd800b improvements, fixes, etc... 2024-06-24 07:07:57 +02:00
Loretta 50869e4754 multiple signalr param; improvements, fixes, etc.. 2024-06-21 14:32:04 +02:00
Loretta 4f600852c8 nuget packages update 2024-06-17 07:03:38 +02:00
jozsef.b@aycode.com e24680a016 TiamGrid.ContextId; improvements, fixes, etc... 2024-06-03 07:45:45 +02:00
jozsef.b@aycode.com f694b7671f Microsoft packages update 2024-05-29 16:20:11 +02:00
jozsef.b@aycode.com ee90982a1f refactroing, improvements, fixes, etc... 2024-05-18 05:14:31 +02:00
jozsef.b@aycode.com 0a3c27c8e4 Login, Register; improvements, fixes, etc... 2024-04-22 17:30:13 +02:00
jozsef.b@aycode.com 0e3c304c2c Update MAUI, Blazor, EfCore, MstTest, SendGrid, etc packages 2024-03-29 06:55:49 +01:00
27 changed files with 1709 additions and 31 deletions

View File

@ -12,9 +12,12 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DevExpress.Blazor" Version="23.2.3" /> <PackageReference Include="DevExpress.Blazor" Version="24.1.3" />
<PackageReference Include="DevExpress.Blazor.Dashboard" Version="23.2.3" /> <PackageReference Include="DevExpress.Blazor.Dashboard" Version="24.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.1" /> <PackageReference Include="MessagePack" Version="2.5.187" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.10" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.10" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="8.0.10" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -0,0 +1,53 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="DevExpress.Blazor" Version="23.2.3" />
<PackageReference Include="DevExpress.Blazor.Dashboard" Version="23.2.3" />
<PackageReference Include="MessagePack" Version="2.5.168" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.6" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.6" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="8.0.6" />
</ItemGroup>
<ItemGroup>
<Reference Include="AyCode.Core">
<HintPath>..\..\AyCode.Core\AyCode.Services.Server\bin\Debug\net8.0\AyCode.Core.dll</HintPath>
</Reference>
<Reference Include="AyCode.Entities">
<HintPath>..\..\AyCode.Core\AyCode.Services.Server\bin\Debug\net8.0\AyCode.Entities.dll</HintPath>
</Reference>
<Reference Include="AyCode.Interfaces">
<HintPath>..\..\AyCode.Core\AyCode.Services.Server\bin\Debug\net8.0\AyCode.Interfaces.dll</HintPath>
</Reference>
<Reference Include="AyCode.Models">
<HintPath>..\..\AyCode.Core\AyCode.Services.Server\bin\Debug\net8.0\AyCode.Models.dll</HintPath>
</Reference>
<Reference Include="AyCode.Services">
<HintPath>..\..\AyCode.Core\AyCode.Services.Server\bin\Debug\net8.0\AyCode.Services.dll</HintPath>
</Reference>
<Reference Include="AyCode.Utils">
<HintPath>..\..\AyCode.Core\AyCode.Services.Server\bin\Debug\net8.0\AyCode.Utils.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Folder Include="Layouts\" />
<Folder Include="Pages\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AyCode.Blazor.Models\AyCode.Blazor.Models.csproj" />
</ItemGroup>
</Project>

View File

@ -1,13 +0,0 @@
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AyCode.Blazor.Components
{
public class ACComponent : ComponentBase
{
}
}

View File

@ -0,0 +1,6 @@
using DevExpress.Blazor;
namespace AyCode.Blazor.Components.Components;
public class AcButton : DxButton
{}

View File

@ -0,0 +1,6 @@
using DevExpress.Blazor;
namespace AyCode.Blazor.Components.Components;
public class AcComboBox<TData, TValue> : DxComboBox<TData, TValue>
{ }

View File

@ -0,0 +1,8 @@
using DevExpress.Blazor.Base;
using Microsoft.AspNetCore.Components;
namespace AyCode.Blazor.Components.Components
{
public abstract class AcComponentBase : DxComponentBase, IComponent, IHandleEvent, IHandleAfterRender
{ }
}

View File

@ -0,0 +1,6 @@
using DevExpress.Blazor;
namespace AyCode.Blazor.Components.Components;
public class AcDxDateEdit<T> : DxDateEdit<T>
{ }

View File

@ -0,0 +1,6 @@
using DevExpress.Blazor;
namespace AyCode.Blazor.Components.Components;
public class AcFormLayoutItem : DxFormLayoutItem
{}

View File

@ -0,0 +1,6 @@
using DevExpress.Blazor;
namespace AyCode.Blazor.Components.Components;
public class AcMaskedInput<T> : DxMaskedInput<T>
{ }

View File

@ -0,0 +1,6 @@
using DevExpress.Blazor;
namespace AyCode.Blazor.Components.Components;
public class AcMemo : DxMemo
{}

View File

@ -0,0 +1,6 @@
using DevExpress.Blazor;
namespace AyCode.Blazor.Components.Components;
public class AcSpinEdit<T> : DxSpinEdit<T>
{}

View File

@ -0,0 +1,6 @@
using DevExpress.Blazor;
namespace AyCode.Blazor.Components.Components;
public class AcTextBox : DxTextBox
{ }

View File

@ -0,0 +1,93 @@
using DevExpress.Blazor;
using DevExpress.Data.Filtering;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AyCode.Core.Interfaces;
using DevExpress.Data.Filtering.Helpers;
using DevExpress.Data.Linq;
using DevExpress.Data.Linq.Helpers;
namespace AyCode.Blazor.Components.Services
{
//public class AcGridDataSource<T> : GridCustomDataSource where T : class, IId<Guid>
//{
// private static readonly AcSignalRDataSource<T> _signalRDataSource;
// public AcGridDataSource(AcSignalRDataSource<T> signalRDataSource)
// {
// _signalRDataSource = signalRDataSource;
// }
// public override Task<IList<GridCustomDataSourceGroupInfo>> GetGroupInfoAsync(GridCustomDataSourceGroupingOptions options, CancellationToken cancellationToken)
// {
// return base.GetGroupInfoAsync(options, cancellationToken);
// }
// public override Task<IList> GetTotalSummaryAsync(GridCustomDataSourceTotalSummaryOptions options, CancellationToken cancellationToken)
// {
// return base.GetTotalSummaryAsync(options, cancellationToken);
// }
// public override Task<object[]> GetUniqueValuesAsync(GridCustomDataSourceUniqueValuesOptions options, CancellationToken cancellationToken)
// {
// return base.GetUniqueValuesAsync(options, cancellationToken);
// }
// public override async Task<int> GetItemCountAsync(GridCustomDataSourceCountOptions options, CancellationToken cancellationToken)
// {
// return await ApplyFiltering(options.FilterCriteria, _signalRDataSource.For<T>()).Count().FindScalarAsync<int>(cancellationToken);
// }
// public override async Task<IList> GetItemsAsync(GridCustomDataSourceItemsOptions options, CancellationToken cancellationToken)
// {
// var filteredClient = ApplyFiltering(options.FilterCriteria, _signalRDataSource.For<T>().Top(options.Count).Skip(options.StartIndex));
// return (await ApplySorting(options, filteredClient).FindEntriesAsync(cancellationToken)).ToList();
// }
// private static IBoundClient<T> ApplyFiltering(CriteriaOperator criteria, IBoundClient<T> boundClient)
// {
// //return !criteria.ReferenceEqualsNull() ? boundClient.Filter(ToSimpleClientCriteria(criteria)) : boundClient;
// CriteriaToExpressionConverter converter = new CriteriaToExpressionConverter();
// //IQueryable<T> source = null!;
// IQueryable<T>? filteredData = _signalRDataSource.AsQueryable().AppendWhere(converter, criteria) as IQueryable<T>;
// gridControl1.DataSource = null;
// gridControl1.DataSource = filteredData.ToList();
// }
// private static string ToSimpleClientCriteria(CriteriaOperator criteria)
// => $"{criteria}".Replace("[", "").Replace("]", "");
// private static IBoundClient<T> ApplySorting(GridCustomDataSourceItemsOptions options, IBoundClient<T> boundClient)
// {
// return options.SortInfo.Any()
// ? boundClient.OrderBy(options.SortInfo
// .Where(info => !info.DescendingSortOrder).Select(info => info.FieldName).ToArray())
// .OrderByDescending(options.SortInfo
// .Where(info => info.DescendingSortOrder).Select(info => info.FieldName).ToArray())
// : boundClient;
// }
// public async Task DeleteAsync(T instance)
// => await _signalRDataSource.For<T>().Key(instance.Id).DeleteEntryAsync();
// public async Task AddOrUpdateAsync(T instance, bool update = false)
// {
// if (!update)
// {
// await _signalRDataSource.For<T>().Set(new { instance.Title, instance.Content }).InsertEntryAsync();
// }
// else
// {
// await _signalRDataSource.For<T>().Key(instance.Id).Set(instance).UpdateEntryAsync();
// }
// }
//}
}

View File

@ -0,0 +1,13 @@
using System.Collections.Concurrent;
using AyCode.Services.Logins;
namespace AyCode.Blazor.Components.Services;
public class AcSessionService<TSessionItem, TSessionItemId> where TSessionItem : IAcSessionItem<TSessionItemId> where TSessionItemId : notnull
{
public ConcurrentDictionary<TSessionItemId, TSessionItem> Sessions { get; private set; } = [];
public AcSessionService()
{
}
}

View File

@ -0,0 +1,284 @@
using System.Collections.Concurrent;
using AyCode.Core;
using AyCode.Core.Extensions;
using AyCode.Core.Helpers;
using AyCode.Core.Loggers;
using AyCode.Interfaces.Entities;
using AyCode.Services.Loggers;
using AyCode.Services.SignalRs;
using MessagePack.Resolvers;
using Microsoft.AspNetCore.SignalR.Client;
namespace AyCode.Blazor.Components.Services
{
public abstract class AcSignalRClientBase : IAcSignalRHubClient
{
private readonly ConcurrentDictionary<int, SignalRRequestModel> _responseByRequestId = new();
protected readonly HubConnection HubConnection;
protected readonly AcLoggerBase Logger;
public event Action<int, byte[], int?> OnMessageReceived = null!;
//public event Action<int, int> OnMessageRequested;
public int Timeout = 10000;
private const string TagsName = "SignalRTags";
protected AcSignalRClientBase(string fullHubName, AcLoggerBase logger)
{
Logger = logger;
HubConnection = new HubConnectionBuilder()
.WithUrl(fullHubName)
//.AddMessagePackProtocol(options => {
// options.SerializerOptions = MessagePackSerializerOptions.Standard
// .WithResolver(MessagePack.Resolvers.StandardResolver.Instance)
// .WithSecurity(MessagePackSecurity.UntrustedData)
// .WithCompression(MessagePackCompression.Lz4Block)
// .WithCompressionMinLength(256);})
.Build();
HubConnection.Closed += HubConnection_Closed;
_ = HubConnection.On<int, byte[], int?>(nameof(IAcSignalRHubClient.OnReceiveMessage), OnReceiveMessage);
//_ = HubConnection.On<int, int>(nameof(IAcSignalRHubClient.OnRequestMessage), OnRequestMessage);
HubConnection.StartAsync().Forget();
}
private Task HubConnection_Closed(Exception? arg)
{
if (_responseByRequestId.IsEmpty) Logger.DebugConditional($"Client HubConnection_Closed");
else Logger.Warning($"Client HubConnection_Closed; {nameof(_responseByRequestId)} count: {_responseByRequestId.Count}");
_responseByRequestId.Clear();
return Task.CompletedTask;
}
public async Task StartConnection()
{
if (HubConnection.State == HubConnectionState.Disconnected)
await HubConnection.StartAsync();
if (HubConnection.State != HubConnectionState.Connected)
await TaskHelper.WaitToAsync(() => HubConnection.State == HubConnectionState.Connected, Timeout, 10, 25);
}
public async Task StopConnection()
{
await HubConnection.StopAsync();
await HubConnection.DisposeAsync();
}
public virtual Task SendMessageToServerAsync(int messageTag)
=> SendMessageToServerAsync(messageTag, null, AcDomain.NextUniqueInt32);
public virtual Task SendMessageToServerAsync(int messageTag, ISignalRMessage? message, int? requestId)
{
Logger.DebugConditional($"Client SendMessageToServerAsync; {nameof(requestId)}: {requestId}; {ConstHelper.NameByValue(TagsName, messageTag)}");
return StartConnection().ContinueWith(_ =>
{
var msgp = message?.ToMessagePack(ContractlessStandardResolver.Options);
return HubConnection.SendAsync(nameof(IAcSignalRHubClient.OnReceiveMessage), messageTag, msgp, requestId);
});
}
#region CRUD
public virtual Task<TResponseData?> GetByIdAsync<TResponseData>(int messageTag, object id) //where TResponseData : class
=> SendMessageToServerAsync<TResponseData>(messageTag, new SignalPostJsonDataMessage<IdMessage>(new IdMessage(id)), AcDomain.NextUniqueInt32);
public virtual Task GetByIdAsync<TResponseData>(int messageTag, Func<ISignalResponseMessage<TResponseData?>, Task> responseCallback, object id)
=> SendMessageToServerAsync(messageTag, new SignalPostJsonDataMessage<IdMessage>(new IdMessage(id)), responseCallback);
public virtual Task<TResponseData?> GetByIdAsync<TResponseData>(int messageTag, object[] ids) //where TResponseData : class
=> SendMessageToServerAsync<TResponseData>(messageTag, new SignalPostJsonDataMessage<IdMessage>(new IdMessage(ids)), AcDomain.NextUniqueInt32);
public virtual Task GetByIdAsync<TResponseData>(int messageTag, Func<ISignalResponseMessage<TResponseData?>, Task> responseCallback, object[] ids)
=> SendMessageToServerAsync(messageTag, new SignalPostJsonDataMessage<IdMessage>(new IdMessage(ids)), responseCallback);
public virtual Task<TResponseData?> GetAllAsync<TResponseData>(int messageTag) //where TResponseData : class
=> SendMessageToServerAsync<TResponseData>(messageTag);
public virtual Task GetAllAsync<TResponseData>(int messageTag, Func<ISignalResponseMessage<TResponseData?>, Task> responseCallback)
=> SendMessageToServerAsync(messageTag, null, responseCallback);
public virtual Task GetAllAsync<TResponseData>(int messageTag, Func<ISignalResponseMessage<TResponseData?>, Task> responseCallback, object[]? contextParams)
=> SendMessageToServerAsync(messageTag, (contextParams == null || contextParams.Length == 0 ? null : new SignalPostJsonDataMessage<IdMessage>(new IdMessage(contextParams))), responseCallback);
public virtual Task<TResponseData?> GetAllAsync<TResponseData>(int messageTag, object[]? contextParams) //where TResponseData : class
=> SendMessageToServerAsync<TResponseData>(messageTag, contextParams == null || contextParams.Length == 0 ? null : new SignalPostJsonDataMessage<IdMessage>(new IdMessage(contextParams)), AcDomain.NextUniqueInt32);
public virtual Task<TPostData?> PostDataAsync<TPostData>(int messageTag, TPostData postData) where TPostData : class
=> SendMessageToServerAsync<TPostData>(messageTag, new SignalPostJsonDataMessage<TPostData>(postData), AcDomain.NextUniqueInt32);
public virtual Task<TResponseData?> PostDataAsync<TPostData, TResponseData>(int messageTag, TPostData postData) //where TPostData : class where TResponseData : class
=> SendMessageToServerAsync<TResponseData>(messageTag, new SignalPostJsonDataMessage<TPostData>(postData), AcDomain.NextUniqueInt32);
public virtual Task PostDataAsync<TPostData>(int messageTag, TPostData postData, Func<ISignalResponseMessage<TPostData?>, Task> responseCallback) //where TPostData : class
=> SendMessageToServerAsync(messageTag, new SignalPostJsonDataMessage<TPostData>(postData), responseCallback);
public virtual Task PostDataAsync<TPostData, TResponseData>(int messageTag, TPostData postData, Func<ISignalResponseMessage<TResponseData?>, Task> responseCallback) //where TPostData : class where TResponseData : class
=> SendMessageToServerAsync(messageTag, new SignalPostJsonDataMessage<TPostData>(postData), responseCallback);
public Task GetAllIntoAsync<TResponseItem>(List<TResponseItem> intoList, int messageTag, object[]? contextParams = null, Action? callback = null) where TResponseItem : IEntityGuid
{
return GetAllAsync<List<TResponseItem>>(messageTag, response =>
{
var logText = $"GetAllIntoAsync<{typeof(TResponseItem).Name}>(); status: {response.Status}; dataCount: {response.ResponseData?.Count}; {ConstHelper.NameByValue(TagsName, messageTag)};";
intoList.Clear();
if (response.Status == SignalResponseStatus.Success && response.ResponseData != null)
{
Logger.Debug(logText);
intoList.AddRange(response.ResponseData);
}
else Logger.Error(logText);
callback?.Invoke();
return Task.CompletedTask;
}, contextParams);
}
#endregion CRUD
public virtual Task<TResponse?> SendMessageToServerAsync<TResponse>(int messageTag) //where TResponse : class
=> SendMessageToServerAsync<TResponse>(messageTag, null, AcDomain.NextUniqueInt32);
public virtual Task<TResponse?> SendMessageToServerAsync<TResponse>(int messageTag, ISignalRMessage? message) //where TResponse : class
=> SendMessageToServerAsync<TResponse>(messageTag, message, AcDomain.NextUniqueInt32);
protected virtual async Task<TResponse?> SendMessageToServerAsync<TResponse>(int messageTag, ISignalRMessage? message, int requestId) //where TResponse : class
{
Logger.DebugConditional($"Client SendMessageToServerAsync<TResult>; {nameof(requestId)}: {requestId}; {ConstHelper.NameByValue(TagsName, messageTag)}");
_responseByRequestId[requestId] = new SignalRRequestModel();
await SendMessageToServerAsync(messageTag, message, requestId);
try
{
if (await TaskHelper.WaitToAsync(() => _responseByRequestId[requestId].ResponseByRequestId != null, Timeout, 25, 50) &&
_responseByRequestId.TryRemove(requestId, out var obj) && obj.ResponseByRequestId is ISignalResponseMessage<string> responseMessage)
{
if (responseMessage.Status == SignalResponseStatus.Error || responseMessage.ResponseData == null)
{
var errorText = $"Client SendMessageToServerAsync<TResponseData> response error; await; tag: {messageTag}; Status: {responseMessage.Status}; requestId: {requestId};";
Logger.Error(errorText);
//TODO: Ideiglenes, majd a ResponseMessage-et kell visszaadni a Status miatt! - J.
return await Task.FromException<TResponse>(new Exception(errorText));
//throw new Exception(errorText);
//return default;
}
return responseMessage.ResponseData.JsonTo<TResponse>();
}
}
catch (Exception ex)
{
Logger.Error($"SendMessageToServerAsync; requestId: {requestId}; {ex.Message}; {ConstHelper.NameByValue(TagsName, messageTag)}", ex);
}
_responseByRequestId.TryRemove(requestId, out _);
return default;
}
public virtual Task SendMessageToServerAsync<TResponseData>(int messageTag, Func<ISignalResponseMessage<TResponseData?>, Task> responseCallback)
=> SendMessageToServerAsync(messageTag, null, responseCallback);
public virtual Task SendMessageToServerAsync<TResponseData>(int messageTag, ISignalRMessage? message, Func<ISignalResponseMessage<TResponseData?>, Task> responseCallback)
{
if (messageTag == 0)
Logger.Error($"SendMessageToServerAsync; messageTag == 0");
var requestId = AcDomain.NextUniqueInt32;
_responseByRequestId[requestId] = new SignalRRequestModel(new Action<ISignalResponseMessage<string>>(responseMessage =>
{
TResponseData? responseData = default;
if (responseMessage.Status == SignalResponseStatus.Success)
{
responseData = string.IsNullOrEmpty(responseMessage.ResponseData) ? default : responseMessage.ResponseData.JsonTo<TResponseData?>();
}
else Logger.Error($"Client SendMessageToServerAsync<TResponseData> response error; callback; Status: {responseMessage.Status}; requestId: {requestId}; {ConstHelper.NameByValue(TagsName, messageTag)}");
responseCallback(new SignalResponseMessage<TResponseData?>(messageTag, responseMessage.Status, responseData));
}));
return SendMessageToServerAsync(messageTag, message, requestId);
}
public virtual Task OnReceiveMessage(int messageTag, byte[] message, int? requestId)
{
var logText = $"Client OnReceiveMessage; {nameof(requestId)}: {requestId}; {ConstHelper.NameByValue(TagsName, messageTag)}";
if (message.Length == 0) Logger.Warning($"message.Length == 0! {logText}");
try
{
if (requestId.HasValue && _responseByRequestId.ContainsKey(requestId.Value))
{
var reqId = requestId.Value;
_responseByRequestId[reqId].ResponseDateTime = DateTime.UtcNow;
Logger.Info($"[{_responseByRequestId[reqId].ResponseDateTime.Subtract(_responseByRequestId[reqId].RequestDateTime).TotalMilliseconds:N0}ms][{(message.Length/1024)}kb]{logText}");
var responseMessage = message.MessagePackTo<SignalResponseJsonMessage>(ContractlessStandardResolver.Options);
switch (_responseByRequestId[reqId].ResponseByRequestId)
{
case null:
_responseByRequestId[reqId].ResponseByRequestId = responseMessage;
return Task.CompletedTask;
case Action<ISignalResponseMessage<string>> messagePackCallback:
_responseByRequestId.TryRemove(reqId, out _);
messagePackCallback.Invoke(responseMessage);
return Task.CompletedTask;
//case Action<string> jsonCallback:
// _responseByRequestId.TryRemove(reqId, out _);
// jsonCallback.Invoke(responseMessage);
// return Task.CompletedTask;
default:
Logger.Error($"Client OnReceiveMessage switch; unknown message type: {_responseByRequestId[reqId].ResponseByRequestId?.GetType().Name}; {ConstHelper.NameByValue(TagsName, messageTag)}");
break;
}
_responseByRequestId.TryRemove(reqId, out _);
}
else Logger.Info(logText);
OnMessageReceived(messageTag, message, requestId);
}
catch (Exception ex)
{
if (requestId.HasValue)
_responseByRequestId.TryRemove(requestId.Value, out _);
Logger.Error($"Client OnReceiveMessage; requestId: {requestId}; {ex.Message}; {ConstHelper.NameByValue(TagsName, messageTag)}", ex);
throw;
}
return Task.CompletedTask;
}
//public virtual Task OnRequestMessage(int messageTag, int requestId)
//{
// Logger.DebugConditional($"Client OnRequestMessage; {nameof(messageTag)}: {messageTag}; {nameof(requestId)}: {requestId};");
// try
// {
// OnMessageRequested(messageTag, requestId);
// }
// catch(Exception ex)
// {
// Logger.Error($"Client OnReceiveMessage; {nameof(messageTag)}: {messageTag}; {nameof(requestId)}: {requestId}; {ex.Message}", ex);
// throw;
// }
// return Task.CompletedTask;
//}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
namespace AyCode.Blazor.Components.Services;
public interface IAcSessionItem<TSessionItemId> where TSessionItemId : notnull
{
public TSessionItemId SessionId { get; set; }
}

View File

@ -0,0 +1,19 @@
namespace AyCode.Blazor.Components.Services;
public class SignalRRequestModel
{
public DateTime RequestDateTime;
public DateTime ResponseDateTime;
public object? ResponseByRequestId = null;
public SignalRRequestModel()
{
RequestDateTime = DateTime.UtcNow;
}
public SignalRRequestModel(object responseByRequestId) : this()
{
ResponseByRequestId = responseByRequestId;
}
}

View File

@ -0,0 +1,46 @@
using System.Reflection;
using AyCode.Core.Extensions;
namespace AyCode.Blazor.Components.Services;
public static class TrackingItemHelpers
{
public static T JsonClone<T>(T source) => source.ToJson().JsonTo<T>()!;
public static T ReflectionClone<T>(T source)
{
var type = source!.GetType();
if (type.IsPrimitive || typeof(string) == type)
return source;
if (type.IsArray)
{
var elementType = Type.GetType(type.FullName!.Replace("[]", string.Empty))!;
var array = (source as Array)!;
var cloned = Array.CreateInstance(elementType, array.Length);
for (var i = 0; i < array.Length; i++)
cloned.SetValue(ReflectionClone(array.GetValue(i)), i);
return (T)Convert.ChangeType(cloned, type);
}
var clone = Activator.CreateInstance(type);
while (type != null && type != typeof(object))
{
foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
{
var fieldValue = field.GetValue(source);
if (fieldValue == null) continue;
field.SetValue(clone, ReflectionClone(fieldValue));
}
type = type.BaseType;
}
return (T)clone!;
}
}

View File

@ -50,4 +50,15 @@
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Loggers\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MessagePack" Version="2.5.187" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.10" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="8.0.10" />
<PackageReference Include="Serialize.Linq" Version="3.1.160" />
</ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,5 @@
namespace AyCode.Blazor.Models.ViewModels;
public abstract class AcDomainViewModel
{
}

View File

@ -0,0 +1,6 @@
namespace AyCode.Blazor.Models.ViewModels;
public abstract class AcGridViewModelBase : AcViewModelBase
{
}

View File

@ -0,0 +1,6 @@
namespace AyCode.Blazor.Models.ViewModels;
public abstract class AcPageViewModelBase : AcViewModelBase
{
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AyCode.Blazor.Models.ViewModels
{
public abstract class AcSiteViewModel : AcDomainViewModel
{
}
}

View File

@ -0,0 +1,6 @@
namespace AyCode.Blazor.Models.ViewModels;
public abstract class AcViewModelBase
{
}

View File

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net8.0;net8.0-maccatalyst;net8.0-ios;net8.0-android</TargetFrameworks> <TargetFrameworks>net8.0;net8.0-maccatalyst;net8.0-ios;net8.0-android34.0</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET --> <!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
<!-- <TargetFrameworks>$(TargetFrameworks);net8.0-tizen</TargetFrameworks> --> <!-- <TargetFrameworks>$(TargetFrameworks);net8.0-tizen</TargetFrameworks> -->
<UseMaui>true</UseMaui> <UseMaui>true</UseMaui>
@ -11,12 +11,18 @@
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion> <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.0</SupportedOSPlatformVersion> <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion> <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">29.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion> <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion> <TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion> <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="MessagePack" Version="2.5.187" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.10" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="8.0.10" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="AyCode.Core"> <Reference Include="AyCode.Core">
<HintPath>..\..\AyCode.Core\AyCode.Services.Server\bin\Debug\net8.0\AyCode.Core.dll</HintPath> <HintPath>..\..\AyCode.Core\AyCode.Services.Server\bin\Debug\net8.0\AyCode.Core.dll</HintPath>
@ -38,12 +44,4 @@
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.Maui.Controls" Version="8.0.6" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.Maui.Controls.Compatibility" Version="8.0.6" />
</ItemGroup>
</Project> </Project>

View File

@ -1,6 +1,4 @@
using System; namespace AyCode.Maui.Core
namespace AyCode.Maui.Core
{ {
// All the code in this file is only included on Tizen. // All the code in this file is only included on Tizen.
public class PlatformClass1 public class PlatformClass1