|
|
|
@ -11,6 +11,24 @@ using Microsoft.AspNetCore.SignalR.Client;
|
|
|
|
|
|
|
|
|
|
|
|
namespace AyCode.Blazor.Components.Services
|
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public abstract class AcSignalRClientBase : IAcSignalRHubClient
|
|
|
|
public abstract class AcSignalRClientBase : IAcSignalRHubClient
|
|
|
|
{
|
|
|
|
{
|
|
|
|
private readonly ConcurrentDictionary<int, SignalRRequestModel> _responseByRequestId = new();
|
|
|
|
private readonly ConcurrentDictionary<int, SignalRRequestModel> _responseByRequestId = new();
|
|
|
|
@ -22,8 +40,8 @@ namespace AyCode.Blazor.Components.Services
|
|
|
|
//public event Action<int, int> OnMessageRequested;
|
|
|
|
//public event Action<int, int> OnMessageRequested;
|
|
|
|
|
|
|
|
|
|
|
|
public int Timeout = 10000;
|
|
|
|
public int Timeout = 10000;
|
|
|
|
private const string TagsName = "SignalRTags";
|
|
|
|
private string _tagsName = "SignalRTags";
|
|
|
|
|
|
|
|
|
|
|
|
protected AcSignalRClientBase(string fullHubName, AcLoggerBase logger)
|
|
|
|
protected AcSignalRClientBase(string fullHubName, AcLoggerBase logger)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Logger = logger;
|
|
|
|
Logger = logger;
|
|
|
|
@ -76,7 +94,7 @@ namespace AyCode.Blazor.Components.Services
|
|
|
|
|
|
|
|
|
|
|
|
public virtual Task SendMessageToServerAsync(int messageTag, ISignalRMessage? message, int? requestId)
|
|
|
|
public virtual Task SendMessageToServerAsync(int messageTag, ISignalRMessage? message, int? requestId)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Logger.DebugConditional($"Client SendMessageToServerAsync; {nameof(requestId)}: {requestId}; {ConstHelper.NameByValue(TagsName, messageTag)}");
|
|
|
|
Logger.DebugConditional($"Client SendMessageToServerAsync; {nameof(requestId)}: {requestId}; {ConstHelper.NameByValue(_tagsName, messageTag)}");
|
|
|
|
|
|
|
|
|
|
|
|
return StartConnection().ContinueWith(_ =>
|
|
|
|
return StartConnection().ContinueWith(_ =>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -86,36 +104,30 @@ namespace AyCode.Blazor.Components.Services
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region CRUD
|
|
|
|
#region CRUD
|
|
|
|
public virtual Task<TResponseData?> GetByIdAsync<TResponseData>(int messageTag, object id) //where TResponseData : class
|
|
|
|
public virtual Task<TResponseData?> GetByIdAsync<TResponseData>(int messageTag, object id) where TResponseData : class
|
|
|
|
=> SendMessageToServerAsync<TResponseData>(messageTag, new SignalPostJsonDataMessage<IdMessage>(new IdMessage(id)), AcDomain.NextUniqueInt32);
|
|
|
|
=> 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)
|
|
|
|
public virtual Task GetByIdAsync<TResponseData>(int messageTag, Func<ISignalResponseMessage<TResponseData?>, Task> responseCallback, object id)
|
|
|
|
=> SendMessageToServerAsync(messageTag, new SignalPostJsonDataMessage<IdMessage>(new IdMessage(id)), responseCallback);
|
|
|
|
=> SendMessageToServerAsync(messageTag, new SignalPostJsonDataMessage<IdMessage>(new IdMessage(id)), responseCallback);
|
|
|
|
|
|
|
|
|
|
|
|
public virtual Task<TResponseData?> GetByIdAsync<TResponseData>(int messageTag, object[] ids) //where TResponseData : class
|
|
|
|
public virtual Task<TResponseData?> GetByIdAsync<TResponseData>(int messageTag, object[] ids) where TResponseData : class
|
|
|
|
=> SendMessageToServerAsync<TResponseData>(messageTag, new SignalPostJsonDataMessage<IdMessage>(new IdMessage(ids)), AcDomain.NextUniqueInt32);
|
|
|
|
=> 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)
|
|
|
|
public virtual Task GetByIdAsync<TResponseData>(int messageTag, Func<ISignalResponseMessage<TResponseData?>, Task> responseCallback, object[] ids)
|
|
|
|
=> SendMessageToServerAsync(messageTag, new SignalPostJsonDataMessage<IdMessage>(new IdMessage(ids)), responseCallback);
|
|
|
|
=> SendMessageToServerAsync(messageTag, new SignalPostJsonDataMessage<IdMessage>(new IdMessage(ids)), responseCallback);
|
|
|
|
|
|
|
|
|
|
|
|
public virtual Task<TResponseData?> GetAllAsync<TResponseData>(int messageTag) //where TResponseData : class
|
|
|
|
public virtual Task<TResponseData?> GetAllAsync<TResponseData>(int messageTag) where TResponseData : class
|
|
|
|
=> SendMessageToServerAsync<TResponseData>(messageTag);
|
|
|
|
=> SendMessageToServerAsync<TResponseData>(messageTag);
|
|
|
|
public virtual Task GetAllAsync<TResponseData>(int messageTag, Func<ISignalResponseMessage<TResponseData?>, Task> responseCallback)
|
|
|
|
public virtual Task GetAllAsync<TResponseData>(int messageTag, Func<ISignalResponseMessage<TResponseData?>, Task> responseCallback)
|
|
|
|
=> SendMessageToServerAsync(messageTag, null, responseCallback);
|
|
|
|
=> SendMessageToServerAsync(messageTag, null, responseCallback);
|
|
|
|
|
|
|
|
|
|
|
|
public virtual Task GetAllAsync<TResponseData>(int messageTag, Func<ISignalResponseMessage<TResponseData?>, Task> responseCallback, object[]? contextParams)
|
|
|
|
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);
|
|
|
|
=> 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
|
|
|
|
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);
|
|
|
|
=> 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
|
|
|
|
public virtual Task<TPostData?> PostDataAsync<TPostData>(int messageTag, TPostData postData) where TPostData : class
|
|
|
|
=> SendMessageToServerAsync<TPostData>(messageTag, new SignalPostJsonDataMessage<TPostData>(postData), AcDomain.NextUniqueInt32);
|
|
|
|
=> 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
|
|
|
|
public virtual Task PostDataAsync<TPostData>(int messageTag, TPostData postData, Func<ISignalResponseMessage<TPostData?>, Task> responseCallback) where TPostData : 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);
|
|
|
|
=> 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<T>(List<T> intoList, int messageTag, object[]? contextParams = null) where T : IEntityGuid
|
|
|
|
public Task GetAllIntoAsync<T>(List<T> intoList, int messageTag, object[]? contextParams = null) where T : IEntityGuid
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -123,7 +135,7 @@ namespace AyCode.Blazor.Components.Services
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (response.Status != SignalResponseStatus.Success || response.ResponseData == null)
|
|
|
|
if (response.Status != SignalResponseStatus.Success || response.ResponseData == null)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Logger.Error($"GetAllIntoAsync<{typeof(T).Name}>(); status: {response.Status}; dataCount: {response.ResponseData?.Count}; {ConstHelper.NameByValue(TagsName, messageTag)};");
|
|
|
|
Logger.Error($"GetAllIntoAsync<{typeof(T).Name}>(); status: {response.Status}; dataCount: {response.ResponseData?.Count}; {ConstHelper.NameByValue(_tagsName, messageTag)};");
|
|
|
|
return Task.CompletedTask;
|
|
|
|
return Task.CompletedTask;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -136,15 +148,15 @@ namespace AyCode.Blazor.Components.Services
|
|
|
|
|
|
|
|
|
|
|
|
#endregion CRUD
|
|
|
|
#endregion CRUD
|
|
|
|
|
|
|
|
|
|
|
|
public virtual Task<TResponse?> SendMessageToServerAsync<TResponse>(int messageTag) //where TResponse : class
|
|
|
|
public virtual Task<TResponse?> SendMessageToServerAsync<TResponse>(int messageTag) where TResponse : class
|
|
|
|
=> SendMessageToServerAsync<TResponse>(messageTag, null, AcDomain.NextUniqueInt32);
|
|
|
|
=> SendMessageToServerAsync<TResponse>(messageTag, null, AcDomain.NextUniqueInt32);
|
|
|
|
|
|
|
|
|
|
|
|
public virtual Task<TResponse?> SendMessageToServerAsync<TResponse>(int messageTag, ISignalRMessage? message) //where TResponse : class
|
|
|
|
public virtual Task<TResponse?> SendMessageToServerAsync<TResponse>(int messageTag, ISignalRMessage? message) where TResponse : class
|
|
|
|
=> SendMessageToServerAsync<TResponse>(messageTag, message, AcDomain.NextUniqueInt32);
|
|
|
|
=> SendMessageToServerAsync<TResponse>(messageTag, message, AcDomain.NextUniqueInt32);
|
|
|
|
|
|
|
|
|
|
|
|
protected virtual async Task<TResponse?> SendMessageToServerAsync<TResponse>(int messageTag, ISignalRMessage? message, int requestId) //where TResponse : class
|
|
|
|
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)}");
|
|
|
|
Logger.DebugConditional($"Client SendMessageToServerAsync<TResult>; {nameof(requestId)}: {requestId}; {ConstHelper.NameByValue(_tagsName, messageTag)}");
|
|
|
|
|
|
|
|
|
|
|
|
_responseByRequestId[requestId] = new SignalRRequestModel();
|
|
|
|
_responseByRequestId[requestId] = new SignalRRequestModel();
|
|
|
|
await SendMessageToServerAsync(messageTag, message, requestId);
|
|
|
|
await SendMessageToServerAsync(messageTag, message, requestId);
|
|
|
|
@ -170,7 +182,7 @@ namespace AyCode.Blazor.Components.Services
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Logger.Error($"SendMessageToServerAsync; requestId: {requestId}; {ex.Message}; {ConstHelper.NameByValue(TagsName, messageTag)}", ex);
|
|
|
|
Logger.Error($"SendMessageToServerAsync; requestId: {requestId}; {ex.Message}; {ConstHelper.NameByValue(_tagsName, messageTag)}", ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_responseByRequestId.TryRemove(requestId, out _);
|
|
|
|
_responseByRequestId.TryRemove(requestId, out _);
|
|
|
|
@ -195,7 +207,7 @@ namespace AyCode.Blazor.Components.Services
|
|
|
|
{
|
|
|
|
{
|
|
|
|
responseData = string.IsNullOrEmpty(responseMessage.ResponseData) ? default : responseMessage.ResponseData.JsonTo<TResponseData?>();
|
|
|
|
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)}");
|
|
|
|
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));
|
|
|
|
responseCallback(new SignalResponseMessage<TResponseData?>(messageTag, responseMessage.Status, responseData));
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
@ -205,7 +217,7 @@ namespace AyCode.Blazor.Components.Services
|
|
|
|
|
|
|
|
|
|
|
|
public virtual Task OnReceiveMessage(int messageTag, byte[] message, int? requestId)
|
|
|
|
public virtual Task OnReceiveMessage(int messageTag, byte[] message, int? requestId)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var logText = $"Client OnReceiveMessage; {nameof(requestId)}: {requestId}; {ConstHelper.NameByValue(TagsName, messageTag)}";
|
|
|
|
var logText = $"Client OnReceiveMessage; {nameof(requestId)}: {requestId}; {ConstHelper.NameByValue(_tagsName, messageTag)}";
|
|
|
|
|
|
|
|
|
|
|
|
if (message.Length == 0) Logger.Warning($"message.Length == 0! {logText}");
|
|
|
|
if (message.Length == 0) Logger.Warning($"message.Length == 0! {logText}");
|
|
|
|
|
|
|
|
|
|
|
|
@ -239,7 +251,7 @@ namespace AyCode.Blazor.Components.Services
|
|
|
|
// return Task.CompletedTask;
|
|
|
|
// return Task.CompletedTask;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
Logger.Error($"Client OnReceiveMessage switch; unknown message type: {_responseByRequestId[reqId].ResponseByRequestId?.GetType().Name}; {ConstHelper.NameByValue(TagsName, messageTag)}");
|
|
|
|
Logger.Error($"Client OnReceiveMessage switch; unknown message type: {_responseByRequestId[reqId].ResponseByRequestId?.GetType().Name}; {ConstHelper.NameByValue(_tagsName, messageTag)}");
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -254,7 +266,7 @@ namespace AyCode.Blazor.Components.Services
|
|
|
|
if (requestId.HasValue)
|
|
|
|
if (requestId.HasValue)
|
|
|
|
_responseByRequestId.TryRemove(requestId.Value, out _);
|
|
|
|
_responseByRequestId.TryRemove(requestId.Value, out _);
|
|
|
|
|
|
|
|
|
|
|
|
Logger.Error($"Client OnReceiveMessage; requestId: {requestId}; {ex.Message}; {ConstHelper.NameByValue(TagsName, messageTag)}", ex);
|
|
|
|
Logger.Error($"Client OnReceiveMessage; requestId: {requestId}; {ex.Message}; {ConstHelper.NameByValue(_tagsName, messageTag)}", ex);
|
|
|
|
throw;
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|