SignalR improvements, fixes, etc..
This commit is contained in:
parent
2036b2afab
commit
1c61c5d328
|
|
@ -16,6 +16,8 @@
|
|||
@using MessagePack
|
||||
@using MessagePack.Resolvers
|
||||
@using AyCode.Core.Extensions;
|
||||
@using AyCode.Core
|
||||
@using AyCode.Core.Helpers
|
||||
@layout AdminLayout
|
||||
@inject IEnumerable<IAcLogWriterClientBase> LogWriters
|
||||
@inject IStringLocalizer<TIAMResources> localizer
|
||||
|
|
@ -387,21 +389,21 @@
|
|||
{
|
||||
_logger = new LoggerClient<ManageTransfers>(LogWriters.ToArray());
|
||||
|
||||
devAdminSignalClient.OnMessageReceived += (messageTag, message) =>
|
||||
devAdminSignalClient.SendRequestToServerAsync(SignalRTags.GetTransfersAsync, responseBytes =>
|
||||
{
|
||||
if (messageTag == SignalRTags.PostTransfersAsync)
|
||||
{
|
||||
var json = message?.MessagePackTo<string>(ContractlessStandardResolver.Options);
|
||||
var transfers = responseBytes.MessagePackTo<string>(ContractlessStandardResolver.Options).JsonTo<List<Transfer>>();
|
||||
|
||||
InitializeDataSources(json?.JsonTo<List<Transfer>>() ?? []);
|
||||
StateHasChanged();
|
||||
}
|
||||
};
|
||||
InitializeDataSources(transfers ?? []);
|
||||
StateHasChanged();
|
||||
}).Forget();
|
||||
|
||||
await devAdminSignalClient.Send("", SignalRTags.GetTransfersAsync, null);
|
||||
|
||||
//var transfers = await devAdminSignalClient.SendRequestToServerAsync<List<Transfer>>(SignalRTags.GetTransfersAsync);
|
||||
//InitializeDataSources(transfers ?? []);
|
||||
|
||||
|
||||
//InitializeDataSources(await transferDataService.GetTransfersAsync());
|
||||
|
||||
base.OnInitialized();
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
private void InitializeDataSources(List<Transfer> transferDataList)
|
||||
|
|
|
|||
|
|
@ -28,16 +28,13 @@
|
|||
|
||||
|
||||
<div class="page">
|
||||
<TiamErrorBoundaryComponent OnError="HandleError">
|
||||
<TiamErrorBoundaryComponent LoggerCategory="AdminLayout" OnError="HandleError">
|
||||
<div class="my-sidebar">
|
||||
|
||||
<AdminNavMenu />
|
||||
</div>
|
||||
|
||||
<main>
|
||||
|
||||
<article class="content">
|
||||
|
||||
@Body
|
||||
</article>
|
||||
</main>
|
||||
|
|
@ -45,54 +42,8 @@
|
|||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
private ILogger _logger;
|
||||
|
||||
public PopupMessageBox PopupMessageBox { get; private set; } = default!;
|
||||
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_logger = new LoggerClient<AdminLayout>(LogWriters.ToArray());
|
||||
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
private void HandleError(Exception exception)//, [CallerMemberName] string? memberName = null)
|
||||
{
|
||||
exception.GetCategoryAndMemberNameFromStackTraceString(out var memberName, out var categoryName);
|
||||
|
||||
if (memberName.IsNullOrWhiteSpace()) memberName = "..."; //ne "HandleError" memberName-el logoljunk! - J.
|
||||
|
||||
try
|
||||
{
|
||||
_logger.Error($"An error occurred: {exception.Message}", exception, categoryName, memberName);
|
||||
}
|
||||
catch (Exception loggerException)
|
||||
{
|
||||
jsRuntime.InvokeVoidAsync("console.error", $"{nameof(AdminLayout)}->HandleError; Logger error! {loggerException}");
|
||||
|
||||
jsRuntime.InvokeVoidAsync("console.error", $"{nameof(AdminLayout)}->{memberName}; An error occurred: {exception}");
|
||||
//jsRuntime.InvokeVoidAsync("console.warn", $"{nameof(AdminLayout)}->{memberName}; Error details: {exception.StackTrace}");
|
||||
}
|
||||
|
||||
// Log the error to server
|
||||
//LogErrorToServer(exception);
|
||||
|
||||
// Show a notification on UI
|
||||
ShowErrorNotification("An unexpected error occurred. Please try again later.");
|
||||
|
||||
//jsRuntime.InvokeVoidAsync("console.error", $"An error occurred: {exception.Message}");
|
||||
//jsRuntime.InvokeVoidAsync("console.warn", $"Error details: {exception.StackTrace}");
|
||||
}
|
||||
|
||||
// private void LogErrorToServer(Exception exception)
|
||||
// {
|
||||
// //_logger.Error($"An error occurred: {exception.Message}");
|
||||
// }
|
||||
|
||||
private void ShowErrorNotification(string message)
|
||||
{
|
||||
jsRuntime.InvokeVoidAsync("alert", message);
|
||||
}
|
||||
private void HandleError(Exception exception) => jsRuntime.InvokeVoidAsync("alert", "An unexpected error occurred. Please try again later.");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,21 @@
|
|||
@inherits ErrorBoundary
|
||||
@using TIAMWebApp.Shared.Application.Utility
|
||||
@using AyCode.Core.Extensions
|
||||
@using AyCode.Services.Loggers
|
||||
@using AyCode.Utils.Extensions
|
||||
@inject IJSRuntime jsRuntime
|
||||
@inject IEnumerable<IAcLogWriterClientBase> LogWriters
|
||||
|
||||
@inherits ErrorBoundary
|
||||
|
||||
|
||||
@if (_currentError != null)
|
||||
{
|
||||
@* <CascadingValue Value=PopupMessageBox> *@
|
||||
<div class="error-message">
|
||||
<p>An error has occurred: @_currentError.Message</p>
|
||||
</div>
|
||||
@* </CascadingValue>
|
||||
<PopupMessageBox @ref="PopupMessageBox" /> *@
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -14,17 +24,55 @@ else
|
|||
|
||||
@code {
|
||||
private Exception? _currentError;
|
||||
private LoggerClient _logger;
|
||||
|
||||
//public PopupMessageBox PopupMessageBox { get; private set; } = default!;
|
||||
|
||||
[Parameter]
|
||||
public string LoggerCategory { get; set; }
|
||||
[Parameter]
|
||||
public EventCallback<Exception> OnError { get; set; }
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_logger = new LoggerClient(LoggerCategory, LogWriters.ToArray());
|
||||
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
// private void HandleError(Exception exception) //, [CallerMemberName] string? memberName = null)
|
||||
// {
|
||||
// }
|
||||
|
||||
protected override Task OnErrorAsync(Exception exception)
|
||||
{
|
||||
_currentError = exception;
|
||||
|
||||
exception.GetCategoryAndMemberNameFromStackTraceString(out var memberName, out var categoryName);
|
||||
|
||||
if (memberName.IsNullOrWhiteSpace()) memberName = "..."; //ne az "OnErrorAsync" memberName-el logoljunk! - J.
|
||||
|
||||
try
|
||||
{
|
||||
_logger.Error($"An error occurred: {exception.Message}", exception, categoryName, memberName);
|
||||
}
|
||||
catch (Exception loggerException)
|
||||
{
|
||||
jsRuntime.InvokeVoidAsync("console.error", $"{nameof(TiamErrorBoundaryComponent)}->OnErrorAsync; Logger error! {loggerException}");
|
||||
|
||||
jsRuntime.InvokeVoidAsync("console.error", $"{nameof(TiamErrorBoundaryComponent)}->{memberName}; An error occurred: {exception}");
|
||||
//jsRuntime.InvokeVoidAsync("console.warn", $"{nameof(TiamErrorBoundaryComponent)}->{memberName}; Error details: {exception.StackTrace}");
|
||||
}
|
||||
|
||||
//ShowErrorNotification("An unexpected error occurred. Please try again later.");
|
||||
return OnError.HasDelegate ? OnError.InvokeAsync(exception) : base.OnErrorAsync(exception);
|
||||
}
|
||||
|
||||
// private void ShowErrorNotification(string message)
|
||||
// {
|
||||
// jsRuntime.InvokeVoidAsync("alert", message);
|
||||
// }
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
_currentError = null;
|
||||
|
|
|
|||
|
|
@ -23,90 +23,32 @@
|
|||
<!--div-- class="page"-->
|
||||
<div>
|
||||
|
||||
<TiamErrorBoundaryComponent OnError="HandleError">
|
||||
<TiamErrorBoundaryComponent LoggerCategory="MainLayout" OnError="HandleError">
|
||||
<AppLaunchComponent />
|
||||
|
||||
<Navbar />
|
||||
<!--div class="my-sidebar">
|
||||
<Navbar />
|
||||
<!--div class="my-sidebar">
|
||||
<NavMenu />
|
||||
</div-->
|
||||
|
||||
<main>
|
||||
<article class="content">
|
||||
<CascadingValue Value=PopupMessageBox>
|
||||
@Body
|
||||
</CascadingValue>
|
||||
</article>
|
||||
</main>
|
||||
@* <div class="footer">
|
||||
</div> *@
|
||||
<FooterComponent></FooterComponent>
|
||||
<PopupMessageBox @ref="PopupMessageBox" />
|
||||
<main>
|
||||
<article class="content">
|
||||
<CascadingValue Value=PopupMessageBox>
|
||||
@Body
|
||||
</CascadingValue>
|
||||
</article>
|
||||
</main>
|
||||
|
||||
@* <div class="footer">
|
||||
</div> *@
|
||||
<FooterComponent></FooterComponent>
|
||||
<PopupMessageBox @ref="PopupMessageBox" />
|
||||
</TiamErrorBoundaryComponent>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@code {
|
||||
private ILogger _logger;
|
||||
|
||||
public PopupMessageBox PopupMessageBox { get; private set; } = default!;
|
||||
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_logger = new LoggerClient<MainLayout>(LogWriters.ToArray());
|
||||
//_logger.Writer<SignaRClientLogItemWriter>()?.StartConnection(Setting.UserBasicDetails?.RefreshToken ?? Guid.NewGuid().ToString("N"));
|
||||
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
// if (firstRender)
|
||||
// _logger.Writer<SignaRClientLogItemWriter>()?.StartConnection(Setting.UserBasicDetails?.RefreshToken ?? Guid.NewGuid().ToString("N"));
|
||||
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
|
||||
private void HandleError(Exception exception)//, [CallerMemberName] string? memberName = null)
|
||||
{
|
||||
exception.GetCategoryAndMemberNameFromStackTraceString(out var memberName, out var categoryName);
|
||||
|
||||
if (memberName.IsNullOrWhiteSpace()) memberName = "..."; //ne "HandleError" memberName-el logoljunk! - J.
|
||||
|
||||
try
|
||||
{
|
||||
_logger.Error($"An error occurred: {exception.Message}", exception, categoryName, memberName);
|
||||
}
|
||||
catch (Exception loggerException)
|
||||
{
|
||||
jsRuntime.InvokeVoidAsync("console.error", $"{nameof(MainLayout)}->HandleError; Logger error! {loggerException}");
|
||||
|
||||
jsRuntime.InvokeVoidAsync("console.error", $"{nameof(MainLayout)}->{memberName}; An error occurred: {exception}");
|
||||
//jsRuntime.InvokeVoidAsync("console.warn", $"{nameof(MainLayout)}->{memberName}; Error details: {exception.StackTrace}");
|
||||
}
|
||||
|
||||
// Log the error to server
|
||||
//LogErrorToServer(exception);
|
||||
|
||||
// Show a notification on UI
|
||||
ShowErrorNotification("An unexpected error occurred. Please try again later.");
|
||||
|
||||
//jsRuntime.InvokeVoidAsync("console.error", $"An error occurred: {exception.Message}");
|
||||
//jsRuntime.InvokeVoidAsync("console.warn", $"Error details: {exception.StackTrace}");
|
||||
}
|
||||
|
||||
// private void LogErrorToServer(Exception exception)
|
||||
// {
|
||||
// //_logger.Error($"An error occurred: {exception.Message}");
|
||||
// }
|
||||
|
||||
private void ShowErrorNotification(string message)
|
||||
{
|
||||
jsRuntime.InvokeVoidAsync("alert", message);
|
||||
}
|
||||
|
||||
private void HandleError(Exception exception) => jsRuntime.InvokeVoidAsync("alert", "An unexpected error occurred. Please try again later.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<PackageReference Include="Blazor.AnimateOnScroll" Version="1.1.0" />
|
||||
<PackageReference Include="BlazorAnimation" Version="2.2.0" />
|
||||
<PackageReference Include="DevExpress.Blazor" Version="23.2.3" />
|
||||
<PackageReference Include="MessagePack" Version="2.5.140" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.5" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ using Microsoft.OpenApi.Models;
|
|||
using System.Text;
|
||||
using AyCode.Core.Loggers;
|
||||
using MessagePack;
|
||||
using MessagePack.Resolvers;
|
||||
using TIAM.Core.Loggers;
|
||||
using TIAM.Database;
|
||||
using TIAM.Database.DataLayers.Admins;
|
||||
|
|
|
|||
|
|
@ -1,52 +1,78 @@
|
|||
using AyCode.Core.Extensions;
|
||||
using AyCode.Core.Helpers;
|
||||
using AyCode.Core.Loggers;
|
||||
using AyCode.Services.SignalRs;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using TIAM.Database.DataLayers.Admins;
|
||||
using MessagePack;
|
||||
using MessagePack.Resolvers;
|
||||
using AyCode.Services.Server.SignalRs;
|
||||
using System.ServiceModel.Channels;
|
||||
|
||||
namespace TIAMWebApp.Server.Services;
|
||||
|
||||
public class DevAdminSignalRHub(AdminDal adminDal, IEnumerable<IAcLogWriterBase> logWriters) : Hub<ISignalRHubServer>, ISignalRHubServer
|
||||
public class DevAdminSignalRHub(AdminDal adminDal, IEnumerable<IAcLogWriterBase> logWriters) : Hub<ISignalRHubItemServer>, IAcSignalRHubServer
|
||||
{
|
||||
private readonly TIAM.Core.Loggers.Logger<DevAdminSignalRHub> _logger = new(logWriters.ToArray());
|
||||
|
||||
// https://docs.microsoft.com/en-us/aspnet/core/signalr/hubs?view=aspnetcore-3.1#strongly-typed-hubs
|
||||
public override async Task OnConnectedAsync()
|
||||
{
|
||||
_logger.Debug($"OnConnectedAsync; ConnectionId: {Context.ConnectionId}; UserIdentifier: {Context.UserIdentifier}");
|
||||
_logger.Debug($"Server OnConnectedAsync; ConnectionId: {Context.ConnectionId}; UserIdentifier: {Context.UserIdentifier}");
|
||||
|
||||
//await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
|
||||
await base.OnConnectedAsync();
|
||||
|
||||
//Clients.Caller.ConnectionId = Context.ConnectionId;
|
||||
//Clients.Caller.UserIdentifier = Context.UserIdentifier;
|
||||
}
|
||||
|
||||
public override async Task OnDisconnectedAsync(Exception? exception)
|
||||
{
|
||||
_logger.Error($"OnDisconnectedAsync; ConnectionId: {Context.ConnectionId}; UserIdentifier: {Context.UserIdentifier}", exception);
|
||||
_logger.Error($"Server OnDisconnectedAsync; ConnectionId: {Context.ConnectionId}; UserIdentifier: {Context.UserIdentifier}", exception);
|
||||
|
||||
//await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR Users");
|
||||
await base.OnDisconnectedAsync(exception);
|
||||
}
|
||||
|
||||
public async Task OnRequestMessage(int messageTag, int requestId)
|
||||
{
|
||||
_logger.Info($"Server OnRequestMessage; {nameof(messageTag)}: {messageTag}; {nameof(requestId)}: {requestId}; ConnectionId: {Context.ConnectionId}; UserIdentifier: {Context.UserIdentifier}");
|
||||
|
||||
if (messageTag == SignalRTags.GetTransfersAsync)
|
||||
await ResponseToCaller(SignalRTags.PostTransfersAsync, await adminDal.GetTransfersJsonAsync(), requestId);
|
||||
}
|
||||
|
||||
public async Task OnReceiveMessage(int messageTag, byte[] message, int? requestId)
|
||||
{
|
||||
var logText = $"Server OnReceiveMessage; {nameof(messageTag)}: {messageTag}; {nameof(requestId)}: {requestId}; ConnectionId: {Context.ConnectionId}; UserIdentifier: {Context.UserIdentifier}";
|
||||
|
||||
if (message.Length == 0) _logger.Warning($"message.Length == 0! {logText}");
|
||||
else _logger.Info(logText);
|
||||
|
||||
//if (messageTag == SignalRTags.GetTransfersAsync)
|
||||
// ResponseToClient(messageTag, await adminDal.GetTransfersJsonAsync(), requestId);
|
||||
}
|
||||
|
||||
protected async Task ResponseToCaller(int messageTag, object message, int requestId)
|
||||
=> await SendMessageToClient(Clients.Caller, messageTag, message, requestId);
|
||||
|
||||
protected async Task SendMessageToClient(ISignalRHubItemServer sendTo, int messageTag, object message, int? requestId = null)
|
||||
{
|
||||
_logger.Info($"Server SendMessageToClient; {nameof(messageTag)}: {messageTag}; {nameof(requestId)}: {requestId}; ConnectionId: {Context.ConnectionId}; UserIdentifier: {Context.UserIdentifier}");
|
||||
|
||||
await sendTo.OnReceiveMessage(messageTag, message.ToMessagePack(ContractlessStandardResolver.Options), requestId);
|
||||
}
|
||||
|
||||
protected void SendRequestToClient(ISignalRHubItemServer sendTo, int messageTag, int requestId)
|
||||
{
|
||||
_logger.Info($"Server SendRequestToClient; {nameof(messageTag)}: {messageTag}; {nameof(requestId)}: {requestId}; ConnectionId: {Context.ConnectionId}; UserIdentifier: {Context.UserIdentifier}");
|
||||
|
||||
sendTo.OnRequestMessage(messageTag, requestId).Forget();
|
||||
}
|
||||
|
||||
public async Task SendMessageToGroup(string groupId, int messageTag, string message)
|
||||
{
|
||||
//await Clients.Group(groupId).Post("", messageTag, message);
|
||||
}
|
||||
|
||||
public async Task Send(string user, int messageTag, object? message)
|
||||
{
|
||||
_logger.Info($"{nameof(user)}: {user}; {nameof(messageTag)}: {messageTag}; ConnectionId: {Context.ConnectionId}; UserIdentifier: {Context.UserIdentifier}");
|
||||
|
||||
await Clients.Caller.MessageReceived("", messageTag, message?.ToMessagePack(ContractlessStandardResolver.Options));
|
||||
}
|
||||
|
||||
public async Task MessageReceived(string user, int messageTag, byte[]? message)
|
||||
{
|
||||
_logger.Info($"{nameof(user)}: {user}; {nameof(messageTag)}: {messageTag}; ConnectionId: {Context.ConnectionId}; UserIdentifier: {Context.UserIdentifier}");
|
||||
|
||||
if (messageTag == SignalRTags.GetTransfersAsync)
|
||||
await Send("", SignalRTags.PostTransfersAsync, await adminDal.GetTransfersJsonAsync());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
namespace TIAMWebApp.Server.Services;
|
||||
|
||||
public interface ISignalRHubServer : IAcSignalRHubServer
|
||||
public interface ISignalRHubItemServer : IAcSignalRHubItemServer
|
||||
{
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
<PackageReference Include="GoogleApi" Version="5.4.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="1.6.14" />
|
||||
<PackageReference Include="QRCoderNetCore" Version="1.0.0" />
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
using AyCode.Core.Enums;
|
||||
using System.Collections.Concurrent;
|
||||
using AyCode.Core;
|
||||
using AyCode.Core.Enums;
|
||||
using AyCode.Core.Extensions;
|
||||
using AyCode.Core.Helpers;
|
||||
using AyCode.Core.Loggers;
|
||||
using AyCode.Entities.LogItems;
|
||||
using AyCode.Services.Loggers;
|
||||
using AyCode.Services.SignalRs;
|
||||
using Azure.Core;
|
||||
using MessagePack;
|
||||
using MessagePack.Resolvers;
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using TIAM.Entities.Transfers;
|
||||
|
|
@ -17,10 +22,13 @@ namespace TIAMWebApp.Shared.Application.Services
|
|||
|
||||
public abstract class AcSignalRClientBase : IAcSignalRHubClient
|
||||
{
|
||||
private readonly ConcurrentDictionary<int, object?> _responseByRequestId = new();
|
||||
|
||||
protected readonly HubConnection HubConnection;
|
||||
protected readonly LoggerClient Logger;
|
||||
|
||||
public event Action<int, byte[]?> OnMessageReceived;
|
||||
public event Action<int, byte[], int?> OnMessageReceived;
|
||||
public event Action<int, int> OnMessageRequested;
|
||||
|
||||
protected AcSignalRClientBase(string hubName, IEnumerable<IAcLogWriterClientBase> logWriters)
|
||||
{
|
||||
|
|
@ -31,9 +39,22 @@ namespace TIAMWebApp.Shared.Application.Services
|
|||
//.AddMessagePackProtocol(options => options.SerializerOptions = MessagePackSerializerOptions.Standard.WithSecurity(MessagePackSecurity.UntrustedData))
|
||||
.Build();
|
||||
|
||||
_ = HubConnection.On<string, int, byte[]?>("MessageReceived", MessageReceived);
|
||||
HubConnection.Closed += HubConnection_Closed;
|
||||
|
||||
_ = HubConnection.On<int, byte[], int?>("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()
|
||||
|
|
@ -42,7 +63,7 @@ namespace TIAMWebApp.Shared.Application.Services
|
|||
await HubConnection.StartAsync();
|
||||
|
||||
if (HubConnection.State != HubConnectionState.Connected)
|
||||
await TaskHelper.WaitToAsync(() => HubConnection.State == HubConnectionState.Connected, 3000, 100);
|
||||
await TaskHelper.WaitToAsync(() => HubConnection.State == HubConnectionState.Connected, 10000, 25);
|
||||
}
|
||||
|
||||
public async Task StopConnection()
|
||||
|
|
@ -51,29 +72,126 @@ namespace TIAMWebApp.Shared.Application.Services
|
|||
await HubConnection.DisposeAsync();
|
||||
}
|
||||
|
||||
public virtual async Task Send(string user, int messageTag, object? message)
|
||||
public virtual async Task SendMessageToServerAsync(int messageTag, object message, int? requestId = null)
|
||||
{
|
||||
Logger.Info($"Send; {nameof(user)}: {user}; {nameof(messageTag)}: {messageTag}");
|
||||
Logger.DebugConditional($"Client SendMessageToServerAsync; {nameof(messageTag)}: {messageTag}; {nameof(requestId)}: {requestId};");
|
||||
|
||||
await StartConnection();
|
||||
HubConnection.SendAsync("MessageReceived", "", messageTag, message).Forget();
|
||||
|
||||
HubConnection.SendAsync(nameof(IAcSignalRHubClient.OnReceiveMessage), messageTag, message, requestId).Forget();
|
||||
}
|
||||
|
||||
public virtual Task MessageReceived(string user, int messageTag, byte[]? message)
|
||||
public virtual void SendRequestToServerAsync(int messageTag)
|
||||
=> SendRequestToServerAsync(messageTag, AcDomain.NextUniqueInt32).Forget();
|
||||
|
||||
public virtual async Task SendRequestToServerAsync(int messageTag, int requestId)
|
||||
{
|
||||
Logger.Info($"MessageReceived; {nameof(user)}: {user}; {nameof(messageTag)}: {messageTag}");
|
||||
Logger.DebugConditional($"Client SendRequestToServerAsync; {nameof(messageTag)}: {messageTag}; {nameof(requestId)}: {requestId};");
|
||||
|
||||
await StartConnection();
|
||||
|
||||
HubConnection.SendAsync(nameof(IAcSignalRHubClient.OnRequestMessage), messageTag, requestId).Forget();
|
||||
}
|
||||
|
||||
public virtual async Task<TResult?> SendRequestToServerAsync<TResult>(int messageTag)
|
||||
{
|
||||
var requestId = AcDomain.NextUniqueInt32;
|
||||
|
||||
Logger.DebugConditional($"Client SendRequestToServerAsync<TResult>; {nameof(messageTag)}: {messageTag}; {nameof(requestId)}: {requestId};");
|
||||
|
||||
_responseByRequestId[requestId] = null;
|
||||
await SendRequestToServerAsync(messageTag, requestId);
|
||||
|
||||
try
|
||||
{
|
||||
OnMessageReceived(messageTag, message);
|
||||
if (await TaskHelper.WaitToAsync(() => _responseByRequestId[requestId] != null, 10000, 25) &&
|
||||
_responseByRequestId.TryRemove(requestId, out var obj) && obj is byte[] messagePackBytes)
|
||||
{
|
||||
var json = messagePackBytes.MessagePackTo<string>(ContractlessStandardResolver.Options);
|
||||
return json.JsonTo<TResult>() ?? default;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"SendRequestToServerAsync; messageTag: {messageTag}; requestId: {requestId}; {ex.Message}", ex);
|
||||
}
|
||||
|
||||
_responseByRequestId.TryRemove(requestId, out _);
|
||||
return default;
|
||||
}
|
||||
|
||||
public virtual Task SendRequestToServerAsync(int messageTag, Action<byte[]> responseCallback)
|
||||
{
|
||||
var requestId = AcDomain.NextUniqueInt32;
|
||||
_responseByRequestId[requestId] = responseCallback;
|
||||
|
||||
return SendRequestToServerAsync(messageTag, requestId);
|
||||
}
|
||||
|
||||
public virtual Task OnReceiveMessage(int messageTag, byte[] message, int? requestId)
|
||||
{
|
||||
var logText = $"Client OnReceiveMessage; {nameof(messageTag)}: {messageTag}; {nameof(requestId)}: {requestId};";
|
||||
|
||||
if (message.Length == 0) Logger.Warning($"message.Length == 0! {logText}");
|
||||
else Logger.Info(logText);
|
||||
|
||||
try
|
||||
{
|
||||
if (requestId.HasValue && _responseByRequestId.ContainsKey(requestId.Value))
|
||||
{
|
||||
var reqId = requestId.Value;
|
||||
|
||||
switch (_responseByRequestId[reqId])
|
||||
{
|
||||
case null:
|
||||
_responseByRequestId[reqId] = message;
|
||||
return Task.CompletedTask;
|
||||
|
||||
case Action<byte[]> messagePackCallback:
|
||||
_responseByRequestId.TryRemove(reqId, out _);
|
||||
|
||||
messagePackCallback.Invoke(message);
|
||||
return Task.CompletedTask;
|
||||
|
||||
//case Action<string> jsonCallback:
|
||||
// jsonCallback.Invoke(message.MessagePackTo<string>());
|
||||
// return Task.CompletedTask;
|
||||
|
||||
default:
|
||||
Logger.Error($"Client OnReceiveMessage switch; unknown message type: {_responseByRequestId[reqId]?.GetType().Name}");
|
||||
break;
|
||||
}
|
||||
|
||||
_responseByRequestId.TryRemove(reqId, out _);
|
||||
}
|
||||
|
||||
OnMessageReceived(messageTag, message, requestId);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Logger.Error($"MessageReceived error; {ex.Message}", ex);
|
||||
Logger.Error($"Client OnReceiveMessage; messageTag: {messageTag}; requestId: {requestId}; {ex.Message}", 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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MessagePack" Version="2.5.140" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.JSInterop" Version="8.0.5" />
|
||||
<PackageReference Include="SkiaSharp" Version="2.88.8" />
|
||||
<PackageReference Include="SkiaSharp.Views.Desktop.Common" Version="2.88.8" />
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ using AyCode.Core.Loggers;
|
|||
using AyCode.Entities;
|
||||
using AyCode.Entities.LogItems;
|
||||
using AyCode.Services.Loggers;
|
||||
using MessagePack;
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
|
|
|||
Loading…
Reference in New Issue