From aae7504589eedc24ad10b4fd72285a040de64b11 Mon Sep 17 00:00:00 2001 From: Loretta Date: Thu, 5 Dec 2024 12:36:05 +0100 Subject: [PATCH] improvements, fixes, etc... --- .../Hubs/AuctionHub.cs | 110 ++++++++++++- .../Hubs/IAuctionHubClient.cs | 1 + .../Hubs/SignalRMessageHandler.cs | 144 +++++++++--------- 3 files changed, 181 insertions(+), 74 deletions(-) diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs index 45e77d8..e894d18 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs @@ -1,14 +1,23 @@ -using Microsoft.AspNetCore.SignalR; +using AyCode.Core.Extensions; +using Microsoft.AspNetCore.SignalR; using Nop.Services.Logging; using Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages; using Nop.Plugin.Misc.AuctionPlugin.Services; +using AyCode.Utils.Extensions; +using Nop.Services.Customers; +using Nop.Core; +using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; +using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities; +using Nop.Core.Domain.Catalog; +using Nop.Core.Domain.Customers; namespace Nop.Plugin.Misc.AuctionPlugin.Hubs { - public class AuctionHub(SessionService sessionService, ILogger logger, SignalRMessageHandler signalRMessageHandler) + public class AuctionHub(SessionService sessionService, ILogger logger, SignalRMessageHandler signalRMessageHandler, IWorkContext workContext, ICustomerService customerService) : Hub { + private readonly SemaphoreSlim _handleMessageMutex = new SemaphoreSlim(1); //HubCallerContext _hubCallerContext; public override async Task OnConnectedAsync() @@ -23,7 +32,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs if (httpContext == null) await logger.ErrorAsync($"AuctionHub.OnConnectedAsync(); (httpContext == null); connectionId: {connectionId}"); else { - if (sessionService.GetOrCreateSessionItem(httpContext.Session.Id) == null) + if (sessionService.GetOrCreateSessionItem(httpContext.Session.Id) == null) await logger.ErrorAsync($"AuctionHub.OnConnectedAsync(); (sessionItem == null); connectionId: {connectionId}; sessionId: {httpContext.Session.Id}"); var userName = httpContext.Request.Query["ConnectionId"]; @@ -50,10 +59,101 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs await Clients.All.SendAsync("Send", message); } - public async Task ReceiveMessageFromClient(MessageWrapper message) + public async Task ReceiveMessageFromClient(MessageWrapper messageWrapper) { var sessionItem = IncrementRequestCount(); - await signalRMessageHandler.HandleMessage(message, sessionItem, Context.ConnectionId); + + await HandleMessageAsync(messageWrapper, sessionItem, Context.ConnectionId); + await SendMessageWrapperAsync(messageWrapper); + } + + public async Task HandleMessageAsync(MessageWrapper messageWrapper, SessionItem sessionItem, string connectionId) + { + var customer = await workContext.GetCurrentCustomerAsync(); + //var connectionId = sessionItem?.SessionId; + + if (messageWrapper?.Data == null) + { + logger.Error($"AuctionHub.HandleMessageAsync(); message?.Data == null; connectionId: {connectionId}", null, customer); + return ResponseType.Error; + } + + if (sessionItem == null || sessionItem.RequestCount != messageWrapper.RequestCount) + await logger.WarningAsync($"AuctionHub.HandleMessageAsync(); sessionItem == null || sessionItem.RequestCount != messageWrapper.RequestCount; connectionId: {connectionId}; sessionId: {sessionItem?.SessionId}; sessionRequests: {sessionItem?.RequestCount}; wrapperRequests: {messageWrapper.RequestCount}", null, customer); + + if (customer == null || messageWrapper.SenderId <= 0 || messageWrapper.SenderId != customer.Id || await customerService.IsGuestAsync(customer)) + { + logger.Error($"AuctionHub.HandleMessageAsync(); (customer == null || message.SenderId <= 0 || message.SenderId != customer.Id || IsGuestAsync() == true); connectionId: {connectionId}", null, customer); + return ResponseType.Error; + } + + await logger.InformationAsync($"AuctionHub.HandleMessageAsync(); Before lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}; jsonData: {messageWrapper.Data}", null, customer); + + //TODO: az összes request-et egy base-ből származtatni és beletenni az AuctionRequestMode-ot! - J. + using (await _handleMessageMutex.UseWaitAsync()) + { + try + { + await logger.InformationAsync($"AuctionHub.HandleMessageAsync(); Enter lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); + + if (messageWrapper.MessageType == "BidRequestMessage") return await signalRMessageHandler.HandleBidRequestAsync(customer, messageWrapper); + else + { + if (!await customerService.IsAdminAsync(customer)) + { + logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); IsAdminAsync() == false; connectionId: {connectionId}", null, customer); + return ResponseType.Error; + } + + switch (messageWrapper.MessageType) + { + case nameof(AuctionProductStatusRequest): + return await signalRMessageHandler.HandleProductToAuctionStatusChangedRequest(customer, messageWrapper); + + case nameof(RevertAuctionBidRequest): + return await signalRMessageHandler.HandleRevertAuctionBidRequest(customer, messageWrapper); + + default: + // Add other message types here + await logger.ErrorAsync($"AuctionHub.HandleMessageAsync(); Unknown message type; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); + return ResponseType.Error; + } + } + + //await logger.InformationAsync($"AuctionHub.HandleMessageAsync(); Exit lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); + } + catch (Exception ex) + { + logger.Error($"AuctionHub.HandleMessageAsync(); switch (message.MessageType); MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}; Exception: {ex.Message}", ex, customer); + } + finally + { + await logger.InformationAsync($"AuctionHub.HandleMessageAsync(); Exit lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); + } + } + + return ResponseType.Error; + } + + public async Task SendMessageWrapperAsync(MessageWrapper messageWrapper) + { + await logger.InformationAsync($"AuctionHub.SendMessageWrapperAsync(); MessageType: {messageWrapper.MessageType}; ResponseType: {messageWrapper.ResponseType}; jsonData: {messageWrapper.Data}"); + + switch (messageWrapper.ResponseType) + { + case ResponseType.ToCaller: + await Clients.Caller.send(messageWrapper.ToJson()); + //await Clients.Caller.SendAsync("send", messageWrapper.ToJson()); + break; + case ResponseType.ToAllClients: + await Clients.All.send(messageWrapper.ToJson()); + //await Clients.All.SendAsync("send", messageWrapper.ToJson()); + break; + case ResponseType.Error: + break; + default: + throw new ArgumentOutOfRangeException(); + } } private SessionItem IncrementRequestCount() diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/IAuctionHubClient.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/IAuctionHubClient.cs index 0d0706c..b787efe 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/IAuctionHubClient.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/IAuctionHubClient.cs @@ -9,6 +9,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs public interface IAuctionHubClient { Task SendAsync(string name, string message); + Task send(string message); Task ReceiveMessageFromClient(string message); Task SendPrice(string price); } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs index fd83c38..a3e538e 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs @@ -29,73 +29,73 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs public class SignalRMessageHandler(ILogger logger, IProductService productService, AuctionService auctionService, IHubContext hubContext, IWorkContext workContext, ICustomerService customerService, ICategoryService categoryService) { - private readonly Mutex _handleMessageMutex = new(); + //private readonly Mutex _handleMessageMutex = new(); - public async Task HandleMessage(MessageWrapper messageWrapper, SessionItem sessionItem, string connectionId) - { - var customer = await workContext.GetCurrentCustomerAsync(); - //var connectionId = sessionItem?.SessionId; + //public async Task HandleMessage(MessageWrapper messageWrapper, SessionItem sessionItem, string connectionId) + //{ + // var customer = await workContext.GetCurrentCustomerAsync(); + // //var connectionId = sessionItem?.SessionId; - if (messageWrapper?.Data == null) - { - logger.Error($"SignalRMessageHandler.HandleMessage(); message?.Data == null; connectionId: {connectionId}", null, customer); - return; - } + // if (messageWrapper?.Data == null) + // { + // logger.Error($"SignalRMessageHandler.HandleMessage(); message?.Data == null; connectionId: {connectionId}", null, customer); + // return; + // } - if (sessionItem == null || sessionItem.RequestCount != messageWrapper.RequestCount) - await logger.WarningAsync($"SignalRMessageHandler.HandleMessage(); sessionItem == null || sessionItem.RequestCount != messageWrapper.RequestCount; connectionId: {connectionId}; sessionId: {sessionItem?.SessionId}; sessionRequests: {sessionItem?.RequestCount}; wrapperRequests: {messageWrapper.RequestCount}", null, customer); + // if (sessionItem == null || sessionItem.RequestCount != messageWrapper.RequestCount) + // await logger.WarningAsync($"SignalRMessageHandler.HandleMessage(); sessionItem == null || sessionItem.RequestCount != messageWrapper.RequestCount; connectionId: {connectionId}; sessionId: {sessionItem?.SessionId}; sessionRequests: {sessionItem?.RequestCount}; wrapperRequests: {messageWrapper.RequestCount}", null, customer); - if (customer == null || messageWrapper.SenderId <= 0 || messageWrapper.SenderId != customer.Id || await customerService.IsGuestAsync(customer)) - { - logger.Error($"SignalRMessageHandler.HandleMessage(); (customer == null || message.SenderId <= 0 || message.SenderId != customer.Id || IsGuestAsync() == true); connectionId: {connectionId}", null, customer); - return; - } + // if (customer == null || messageWrapper.SenderId <= 0 || messageWrapper.SenderId != customer.Id || await customerService.IsGuestAsync(customer)) + // { + // logger.Error($"SignalRMessageHandler.HandleMessage(); (customer == null || message.SenderId <= 0 || message.SenderId != customer.Id || IsGuestAsync() == true); connectionId: {connectionId}", null, customer); + // return; + // } - await logger.InformationAsync($"SignalRMessageHandler.HandleMessage(); Before lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}; jsonData: {messageWrapper.Data}", null, customer); + // await logger.InformationAsync($"SignalRMessageHandler.HandleMessage(); Before lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}; jsonData: {messageWrapper.Data}", null, customer); - //TODO: az összes request-et egy base-ből származtatni és beletenni az AuctionRequestMode-ot! - J. - using (_handleMessageMutex.UseWaitOne()) - { - try - { - await logger.InformationAsync($"SignalRMessageHandler.HandleMessage(); Enter lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); + // //TODO: az összes request-et egy base-ből származtatni és beletenni az AuctionRequestMode-ot! - J. + // using (_handleMessageMutex.UseWaitOne()) + // { + // try + // { + // await logger.InformationAsync($"SignalRMessageHandler.HandleMessage(); Enter lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); - if (messageWrapper.MessageType == "BidRequestMessage") await HandleBidRequest(customer, messageWrapper); - else - { - if (!await customerService.IsAdminAsync(customer)) - { - logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); IsAdminAsync() == false; connectionId: {connectionId}", null, customer); - return; - } + // if (messageWrapper.MessageType == "BidRequestMessage") await HandleBidRequest(customer, messageWrapper); + // else + // { + // if (!await customerService.IsAdminAsync(customer)) + // { + // logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); IsAdminAsync() == false; connectionId: {connectionId}", null, customer); + // return; + // } - switch (messageWrapper.MessageType) - { - case nameof(AuctionProductStatusRequest): - await HandleProductToAuctionStatusChangedRequest(customer, messageWrapper); - break; + // switch (messageWrapper.MessageType) + // { + // case nameof(AuctionProductStatusRequest): + // await HandleProductToAuctionStatusChangedRequest(customer, messageWrapper); + // break; - case nameof(RevertAuctionBidRequest): - await HandleRevertAuctionBidRequest(customer, messageWrapper); - break; + // case nameof(RevertAuctionBidRequest): + // await HandleRevertAuctionBidRequest(customer, messageWrapper); + // break; - default: - // Add other message types here - await logger.ErrorAsync($"SignalRMessageHandler.HandleMessage(); Unknown message type; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); - break; - } - } + // default: + // // Add other message types here + // await logger.ErrorAsync($"SignalRMessageHandler.HandleMessage(); Unknown message type; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); + // break; + // } + // } - await logger.InformationAsync($"SignalRMessageHandler.HandleMessage(); Exit lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); - } - catch (Exception ex) - { - logger.Error($"SignalRMessageHandler.HandleMessage(); switch (message.MessageType); MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}; Exception: {ex.Message}", ex, customer); - } - } - } + // await logger.InformationAsync($"SignalRMessageHandler.HandleMessage(); Exit lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); + // } + // catch (Exception ex) + // { + // logger.Error($"SignalRMessageHandler.HandleMessage(); switch (message.MessageType); MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}; Exception: {ex.Message}", ex, customer); + // } + // } + //} - private async Task HandleRevertAuctionBidRequest(Customer customer, MessageWrapper messageWrapper) + public async Task HandleRevertAuctionBidRequest(Customer customer, MessageWrapper messageWrapper) { var revertAuctionBidRequest = messageWrapper.Data.JsonTo(); if (revertAuctionBidRequest == null) @@ -127,7 +127,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs await SetAuctionBidPrice(revertLastBid.BidPrice, productToAuction, product, revertLastBid.CustomerId); } - await SendAuctionBidMessageAsync(messageWrapper, productToAuction, product, customer.Id); + await SendAuctionBidMessageAsync(messageWrapper, productToAuction, product, customer.Id, ResponseType.ToAllClients); return ResponseType.ToAllClients; } catch (Exception ex) @@ -138,7 +138,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs return ResponseType.Error; } - private async Task HandleProductToAuctionStatusChangedRequest(Customer customer, MessageWrapper messageWrapper) + public async Task HandleProductToAuctionStatusChangedRequest(Customer customer, MessageWrapper messageWrapper) { var auctionProductStatusRequest = messageWrapper.Data.JsonTo(); if (auctionProductStatusRequest == null) @@ -252,23 +252,23 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs } - private async Task HandleBidRequest(Customer customer, MessageWrapper messageWrapper) + public async Task HandleBidRequestAsync(Customer customer, MessageWrapper messageWrapper) { var bidRequestMessage = messageWrapper.Data.JsonTo(); if (bidRequestMessage == null) { - logger.Error($"SignalRMessageHandler.HandleBidRequest(); (bidRequestMessage == null)", null, customer); + logger.Error($"SignalRMessageHandler.HandleBidRequestAsync(); (bidRequestMessage == null)", null, customer); return ResponseType.Error; } try { - await logger.InformationAsync($"SignalRMessageHandler.HandleBidRequest(); Bid received; Auction: {bidRequestMessage.AuctionId}; ProductToAuction: {bidRequestMessage.ProductAuctionMappingId}; Product: {bidRequestMessage.ProductId}; Bid: {bidRequestMessage.BidPrice}; Customer: {bidRequestMessage.CustomerId}", null, customer); + await logger.InformationAsync($"SignalRMessageHandler.HandleBidRequestAsync(); Bid received; Auction: {bidRequestMessage.AuctionId}; ProductToAuction: {bidRequestMessage.ProductAuctionMappingId}; Product: {bidRequestMessage.ProductId}; Bid: {bidRequestMessage.BidPrice}; Customer: {bidRequestMessage.CustomerId}", null, customer); var auction = await auctionService.GetAuctionDtoByIdAsync(bidRequestMessage.AuctionId, false, false); if (auction == null || auction.Closed) { - logger.Warning($"SignalRMessageHandler.HandleBidRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer); + logger.Warning($"SignalRMessageHandler.HandleBidRequestAsync(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer); return ResponseType.Error; } @@ -278,14 +278,16 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs var activeProductAuction = (await auctionService.GetProductToAuctionByAuctionIdAndProductIdAsync(bidRequestMessage.AuctionId, bidRequestMessage.ProductId, true)).FirstOrDefault(); if (activeProductAuction is not { IsActiveItem: true } || (activeProductAuction.WinnerCustomerId == customer.Id && !await customerService.IsAdminAsync(customer))) { - logger.Warning($"SignalRMessageHandler.HandleBidRequest(); (activeProductAuction is not {{ IsActiveItem: true }} || activeProductAuction.WinnerCustomerId == customer.Id && !await customerService.IsAdminAsync(customer)); AuctionStatus: {activeProductAuction?.AuctionStatus}; WinnerCustomerId: {activeProductAuction?.WinnerCustomerId}", null, customer); - await SendAuctionBidMessageAsync(messageWrapper, activeProductAuction, product, customer.Id);//, false); + logger.Warning($"SignalRMessageHandler.HandleBidRequestAsync(); (activeProductAuction is not {{ IsActiveItem: true }} || activeProductAuction.WinnerCustomerId == customer.Id && !await customerService.IsAdminAsync(customer)); AuctionStatus: {activeProductAuction?.AuctionStatus}; WinnerCustomerId: {activeProductAuction?.WinnerCustomerId}", null, customer); + await UpdateBidNotificationMessageWrapperAsync(messageWrapper, activeProductAuction, product, customer.Id, ResponseType.ToCaller); + return ResponseType.ToCaller; } if (!IsValidBidPrice(activeProductAuction.CurrentPrice, bidRequestMessage.BidPrice, activeProductAuction.BidsCount > 0, customer)) { - await SendAuctionBidMessageAsync(messageWrapper, activeProductAuction, product, customer.Id);//, false); + await UpdateBidNotificationMessageWrapperAsync(messageWrapper, activeProductAuction, product, customer.Id, ResponseType.ToCaller); + return ResponseType.ToCaller; } @@ -298,12 +300,12 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs activeProductAuction.AuctionStatus = AuctionStatus.Active; if (!await SetAuctionBidPrice(auctionBid.BidPrice, activeProductAuction, product, customer.Id)) return ResponseType.Error; - await SendAuctionBidMessageAsync(messageWrapper, activeProductAuction, product, customer.Id); + await UpdateBidNotificationMessageWrapperAsync(messageWrapper, activeProductAuction, product, customer.Id, ResponseType.ToAllClients); return ResponseType.ToAllClients; } catch (Exception ex) { - logger.Error($"SignalRMessageHandler.HandleBidRequest(); Exception: {ex.Message}", ex, customer); + logger.Error($"SignalRMessageHandler.HandleBidRequestAsync(); Exception: {ex.Message}", ex, customer); } return ResponseType.Error; @@ -331,7 +333,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs return false; } - private async Task SendAuctionBidMessageAsync(MessageWrapper messageWrapper, ProductToAuctionMapping productToAuction, Product product, int customerId, bool sendToCaller = false) + public async Task UpdateBidNotificationMessageWrapperAsync(MessageWrapper messageWrapper, ProductToAuctionMapping productToAuction, Product product, int customerId, ResponseType responseType) { var bidsCount = productToAuction.BidsCount; //await auctionService.GetBidsCountByProductToAuctionIdAsync(productToAuction.Id); @@ -339,7 +341,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs var nextBidPrice = GetNextBidPrice(productToAuction.CurrentPrice, stepAmount, bidsCount > 0); messageWrapper.SenderId = customerId; - messageWrapper.ResponseType = sendToCaller ? ResponseType.ToCaller : ResponseType.ToAllClients; + messageWrapper.ResponseType = responseType; messageWrapper.MessageType = "bidNotification"; messageWrapper.Data = new BidNotificationMessage(await auctionService.GetAuctionDtoByProductToAuctionIdAsync(productToAuction.Id, true), bidsCount, "EMPTY") //TODO: NE KÉRJÜK LE DB-BŐL!!! - J. { @@ -348,8 +350,12 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs NextStepAmount = stepAmount, NextBidPrice = nextBidPrice, }.ToJson(); + } - await SendMessageToClientsAsync(messageWrapper, sendToCaller); + public async Task SendAuctionBidMessageAsync(MessageWrapper messageWrapper, ProductToAuctionMapping productToAuction, Product product, int customerId, ResponseType responseType) + { + await UpdateBidNotificationMessageWrapperAsync(messageWrapper, productToAuction, product, customerId, responseType); + await SendMessageToClientsAsync(messageWrapper, responseType == ResponseType.ToCaller); } private async Task StepNextProductToAuctionAsync(MessageWrapper messageWrapper, Customer customer, ProductToAuctionMapping productToAuction, AuctionProductStatusRequest auctionProductStatusRequest)