From 99f60ad70df0b6db2986faf602d03e74de7cd7e1 Mon Sep 17 00:00:00 2001 From: Loretta Date: Wed, 4 Dec 2024 07:54:10 +0100 Subject: [PATCH] improvements, fixes, etc... --- .../Domains/Enums/ResponseType.cs | 8 + .../EventConsumers/AuctionEventConsumer.cs | 4 +- .../Hubs/AuctionHub.cs | 3 +- .../Hubs/Messages/MessageWrapper.cs | 5 +- .../Hubs/SignalRMessageHandler.cs | 172 ++++++++++-------- 5 files changed, 117 insertions(+), 75 deletions(-) create mode 100644 Nop.Plugin.Misc.AuctionPlugin/Domains/Enums/ResponseType.cs diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/Enums/ResponseType.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/Enums/ResponseType.cs new file mode 100644 index 0000000..fc0f211 --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/Enums/ResponseType.cs @@ -0,0 +1,8 @@ +namespace Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; + +public enum ResponseType : byte +{ + Error = 0, + ToCaller = 10, + ToAllClients = 20, +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/EventConsumers/AuctionEventConsumer.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/EventConsumers/AuctionEventConsumer.cs index 80921ca..fbaabbe 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Domains/EventConsumers/AuctionEventConsumer.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/EventConsumers/AuctionEventConsumer.cs @@ -19,9 +19,9 @@ public class AuctionEventConsumer(IHttpContextAccessor httpContextAccessor, ILog foreach (var productToAuction in productToAuctions) { - if (await ctx.HasBidByProductToAuctionIdAsync(productToAuction.Id)) + if (productToAuction.BidsCount > 0) //await ctx.HasBidByProductToAuctionIdAsync(productToAuction.Id)) { - await Logger.InformationAsync($"AuctionEventConsumer.HandleEventAsync(); HasAuctionBids->continue"); + await Logger.InformationAsync($"AuctionEventConsumer.HandleEventAsync(); HasAuctionBids->continue; productId: {eventMessage.Entity.Id}; productToAuctionId: {productToAuction.Id};"); continue; } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs index 2d7d895..193bb01 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs @@ -12,6 +12,7 @@ using Nop.Services.Catalog; using Nop.Plugin.Misc.AuctionPlugin.Services; using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities; using Newtonsoft.Json.Linq; +using static LinqToDB.Reflection.Methods.LinqToDB.Insert; namespace Nop.Plugin.Misc.AuctionPlugin.Hubs { @@ -65,7 +66,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs // Log the message type and data //await _logger.InformationAsync($"AuctionHub.OnConnectedAsync(); Received message of type: {message.MessageType}"); - await _signalRMessageHandler.HandleMessage(message); + await _signalRMessageHandler.HandleMessage(message, Context.ConnectionId); } } } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageWrapper.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageWrapper.cs index 3ee0eb2..cc634b0 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageWrapper.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageWrapper.cs @@ -1,4 +1,5 @@ -using System; +using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -10,6 +11,8 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages { public string MessageType { get; set; } public int SenderId { get; set; } + public Guid RequestId { get; set; } + public ResponseType ResponseType { get; set; } public string Data { get; set; } } } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs index 82fbe49..bd341f5 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs @@ -30,68 +30,73 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs { private readonly Mutex _handleMessageMutex = new(); - public async Task HandleMessage(MessageWrapper message) + public async Task HandleMessage(MessageWrapper messageWrapper, string connectionId) { var customer = await workContext.GetCurrentCustomerAsync(); - if (message?.Data == null) + if (messageWrapper?.Data == null) { - logger.Error($"SignalRMessageHandler.HandleMessage(); message?.Data == null", null, customer); + logger.Error($"SignalRMessageHandler.HandleMessage(); message?.Data == null; connectionId: {connectionId}", null, customer); return; } - await logger.InformationAsync($"SignalRMessageHandler.HandleMessage(); MessageType: {message.MessageType}; jsonData: {message.Data}", null, customer); - - if (customer == null || message.SenderId <= 0 || message.SenderId != customer.Id || await customerService.IsGuestAsync(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)", null, 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); + //TODO: az összes request-et egy base-ből származtatni és beletenni az AuctionRequestMode-ot! - J. using (_handleMessageMutex.UseWaitOne()) { try { - if (message.MessageType == "BidRequestMessage") await HandleBidRequest(customer, message.Data.JsonTo()); + 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!", null, customer); + logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); IsAdminAsync() == false; connectionId: {connectionId}", null, customer); return; } - switch (message.MessageType) + switch (messageWrapper.MessageType) { case nameof(AuctionProductStatusRequest): - await HandleProductToAuctionStatusChangedRequest(customer, message.Data.JsonTo()); + await HandleProductToAuctionStatusChangedRequest(customer, messageWrapper); break; case nameof(RevertAuctionBidRequest): - await HandleRevertAuctionBidRequest(customer, message.Data.JsonTo()); + await HandleRevertAuctionBidRequest(customer, messageWrapper); break; default: // Add other message types here - await logger.ErrorAsync($"SignalRMessageHandler.HandleMessage(); Unknown message type; MessageType: {message.MessageType}", null, customer); + 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: {message.MessageType}; Exception: {ex.Message}", ex, customer); + logger.Error($"SignalRMessageHandler.HandleMessage(); switch (message.MessageType); MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}; Exception: {ex.Message}", ex, customer); } } } - private async Task HandleRevertAuctionBidRequest(Customer customer, RevertAuctionBidRequest revertAuctionBidRequest) + private async Task HandleRevertAuctionBidRequest(Customer customer, MessageWrapper messageWrapper) { + var revertAuctionBidRequest = messageWrapper.Data.JsonTo(); if (revertAuctionBidRequest == null) { logger.Error($"SignalRMessageHandler.HandleRevertAuctionBidRequest(); auctionProductStatusRequest == null", null, customer); - return; + return ResponseType.Error; } try @@ -100,13 +105,13 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs if (productToAuction is not { AuctionStatus: AuctionStatus.Pause }) { logger.Warning($"SignalRMessageHandler.HandleRevertAuctionBidRequest(); (productToAuction is not {{ AuctionStatus: AuctionStatus.Pause }}); AuctionStatus: {productToAuction?.AuctionStatus}", null, customer); - return; + return ResponseType.Error; } await logger.InformationAsync($"SignalRMessageHandler.HandleRevertAuctionBidRequest(); (productToAuction is not {{ AuctionStatus: AuctionStatus.Pause }}); AuctionStatus: {productToAuction.AuctionStatus}", null, customer); var product = await auctionService.GetProductById(productToAuction.ProductId); - if (product == null) return; + if (product == null) return ResponseType.Error; var revertLastBid = await auctionService.RevertAuctionBidByProductToAuctionIdAsync(productToAuction.Id); @@ -117,47 +122,52 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs await SetAuctionBidPrice(revertLastBid.BidPrice, productToAuction, product, revertLastBid.CustomerId); } - await SendAuctionBidMessageAsync(productToAuction, product, customer.Id); + await SendAuctionBidMessageAsync(messageWrapper, productToAuction, product, customer.Id); + return ResponseType.ToAllClients; } catch (Exception ex) { logger.Error($"SignalRMessageHandler.HandleRevertAuctionBidRequest(); Exception: {ex.Message}", ex, customer); } + + return ResponseType.Error; } - private async Task HandleProductToAuctionStatusChangedRequest(Customer customer, AuctionProductStatusRequest auctionProductStatusRequest) + private async Task HandleProductToAuctionStatusChangedRequest(Customer customer, MessageWrapper messageWrapper) { + var auctionProductStatusRequest = messageWrapper.Data.JsonTo(); if (auctionProductStatusRequest == null) { logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); auctionProductStatusRequest == null", null, customer); - return; + return ResponseType.Error;; } try { + var responseType = ResponseType.ToAllClients; await logger.InformationAsync($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); ProductToAuctionMappingId: {auctionProductStatusRequest.ProductToAuctionId}; Status: {auctionProductStatusRequest.AuctionStatus}({(int)auctionProductStatusRequest.AuctionStatus})", null, customer); var productToAuction = await auctionService.GetProductToAuctionMappingByIdAsync(auctionProductStatusRequest.ProductToAuctionId); if (productToAuction == null) { logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (productToAuction == null)", null, customer); - return; + return ResponseType.Error;; } var auction = await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId); if (auction == null || auction.Closed) { logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer); - return; + return ResponseType.Error;; } - + if (!IsValidRequestAuctionStatus(auctionProductStatusRequest.AuctionStatus, productToAuction.AuctionStatus)) { + responseType = ResponseType.ToCaller; logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); RequestAuctionStatusIsValid() == false; newStatus: {auctionProductStatusRequest.AuctionStatus}; oldStatus: {productToAuction.AuctionStatus}", null, customer); - return; + //return ResponseType.Error;; } - - if (auctionProductStatusRequest.AuctionStatus == AuctionStatus.None) await ResetProductToAuction(productToAuction, auction.CategoryId); + else if (auctionProductStatusRequest.AuctionStatus == AuctionStatus.None) await ResetProductToAuction(productToAuction, auction.CategoryId); else { switch (auctionProductStatusRequest.AuctionStatus) @@ -198,7 +208,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs default: logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); AuctionStatus not found; (auctionProductStatusRequest.AuctionStatus == {auctionProductStatusRequest.AuctionStatus})", null, customer); - return; + return ResponseType.Error;; } await auctionService.UpdateProductToAuctionMappingAsync(productToAuction); @@ -209,46 +219,41 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs { MessageType = nameof(ProductToAuctionStatusNotification), SenderId = customer.Id, + ResponseType = responseType, Data = new ProductToAuctionStatusNotification(await auctionService.GetAuctionDtoByProductToAuctionIdAsync(productToAuction.Id, true), bidsCount, "EMPTY").ToJson() }; - await hubContext.Clients.All.SendAsync("send", productToauctionChangedNotification.ToJson()); + await SendMessageToClientsAsync(productToauctionChangedNotification, responseType == ResponseType.ToCaller); //TODO: gond van ha az Admin valamit módosít és újrazár egy régi ProductToAuction-t!!!! AuctionRequestMode.Normal...- J. - if (/*AuctionRequestMode.Normal &&*/ auction.AuctionType == AuctionType.AutomaticNext && productToAuction.AuctionStatus is AuctionStatus.Sold or AuctionStatus.NotSold) - await StepNextProductToAuctionAsync(customer, productToAuction, auctionProductStatusRequest); + if (responseType== ResponseType.ToAllClients && /*AuctionRequestMode.Normal &&*/ auction.AuctionType == AuctionType.AutomaticNext && productToAuction.AuctionStatus is AuctionStatus.Sold or AuctionStatus.NotSold) + await StepNextProductToAuctionAsync(messageWrapper, customer, productToAuction, auctionProductStatusRequest); + + return ResponseType.ToAllClients; } catch (Exception ex) { logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); Exception: {ex.Message}", ex, customer); } + + return ResponseType.Error; } - private async Task StepNextProductToAuctionAsync(Customer customer, ProductToAuctionMapping productToAuction, AuctionProductStatusRequest auctionProductStatusRequest) + private async Task SendMessageToClientsAsync(MessageWrapper messageWrapper, bool sendToCaller = false) { - var nextProductToAuction = await auctionService.GetNextProductToAuctionByAuctionIdAsync(productToAuction.AuctionId); - if (nextProductToAuction == null) return; - - await logger.InformationAsync($"SignalRMessageHandler.StepNextProductToAuctionAsync(); NextProductToAuctionId: {nextProductToAuction.Id};", null, customer); - - if (nextProductToAuction.AuctionStatus != AuctionStatus.None) - { - await logger.WarningAsync($"SignalRMessageHandler.StepNextProductToAuctionAsync(); (nextProductToAuction.AuctionStatus != AuctionStatus.None); NextProductToAuctionId: {nextProductToAuction.Id}; Status: {nextProductToAuction.AuctionStatus}({(int)nextProductToAuction.AuctionStatus})", null, customer); - return; //TODO: Ilyenkor mi legyen?! - J. - } - - auctionProductStatusRequest.AuctionStatus = AuctionStatus.Active; - auctionProductStatusRequest.ProductToAuctionId = nextProductToAuction.Id; - - await HandleProductToAuctionStatusChangedRequest(customer, auctionProductStatusRequest); + //if (sendToCaller) await hubContext.Clients.Caller.SendAsync("send", bidMessage.ToJson()); + //else + await hubContext.Clients.All.SendAsync("send", messageWrapper.ToJson()); } - private async Task HandleBidRequest(Customer customer, AuctionBidRequest bidRequestMessage) + + private async Task HandleBidRequest(Customer customer, MessageWrapper messageWrapper) { + var bidRequestMessage = messageWrapper.Data.JsonTo(); if (bidRequestMessage == null) { logger.Error($"SignalRMessageHandler.HandleBidRequest(); (bidRequestMessage == null)", null, customer); - return; + return ResponseType.Error;; } try @@ -259,20 +264,25 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs if (auction == null || auction.Closed) { logger.Warning($"SignalRMessageHandler.HandleBidRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer); - return; + return ResponseType.Error;; } + var product = await auctionService.GetProductById(bidRequestMessage.ProductId); + if (product == null) return ResponseType.Error;; + 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); - return; + await SendAuctionBidMessageAsync(messageWrapper, activeProductAuction, product, customer.Id);//, false); + return ResponseType.ToCaller; } - var product = await auctionService.GetProductById(bidRequestMessage.ProductId); - if (product == null) return; - - if (!IsValidBidPrice(activeProductAuction.CurrentPrice, bidRequestMessage.BidPrice, activeProductAuction.BidsCount > 0, customer)) return; + if (!IsValidBidPrice(activeProductAuction.CurrentPrice, bidRequestMessage.BidPrice, activeProductAuction.BidsCount > 0, customer)) + { + await SendAuctionBidMessageAsync(messageWrapper, activeProductAuction, product, customer.Id);//, false); + return ResponseType.ToCaller; + } var auctionBid = bidRequestMessage.CreateMainEntity(); auctionBid.ProductAuctionMappingId = activeProductAuction.Id; @@ -281,14 +291,17 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs activeProductAuction.BidsCount++; activeProductAuction.AuctionStatus = AuctionStatus.Active; - if (!await SetAuctionBidPrice(auctionBid.BidPrice, activeProductAuction, product, customer.Id)) return; + if (!await SetAuctionBidPrice(auctionBid.BidPrice, activeProductAuction, product, customer.Id)) return ResponseType.Error; - await SendAuctionBidMessageAsync(activeProductAuction, product, customer.Id); + await SendAuctionBidMessageAsync(messageWrapper, activeProductAuction, product, customer.Id); + return ResponseType.ToAllClients; } catch (Exception ex) { logger.Error($"SignalRMessageHandler.HandleBidRequest(); Exception: {ex.Message}", ex, customer); } + + return ResponseType.Error; } private async Task SetAuctionBidPrice(decimal bidPrice, ProductToAuctionMapping productToAuction, Product product, int lastBidCustomerId) @@ -313,27 +326,44 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs return false; } - private async Task SendAuctionBidMessageAsync(ProductToAuctionMapping productToAuction, Product product, int customerId) + private async Task SendAuctionBidMessageAsync(MessageWrapper messageWrapper, ProductToAuctionMapping productToAuction, Product product, int customerId, bool sendToCaller = false) { - var bidsCount = productToAuction.BidsCount;//await auctionService.GetBidsCountByProductToAuctionIdAsync(productToAuction.Id); + var bidsCount = productToAuction.BidsCount; //await auctionService.GetBidsCountByProductToAuctionIdAsync(productToAuction.Id); var stepAmount = GetStepAmount(productToAuction.CurrentPrice); var nextBidPrice = GetNextBidPrice(productToAuction.CurrentPrice, stepAmount, bidsCount > 0); - var bidMessage = new MessageWrapper + messageWrapper.SenderId = customerId; + messageWrapper.ResponseType = sendToCaller ? ResponseType.ToCaller : ResponseType.ToAllClients; + 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. { - MessageType = "bidNotification", - SenderId = customerId, - Data = new BidNotificationMessage(await auctionService.GetAuctionDtoByProductToAuctionIdAsync(productToAuction.Id, true), bidsCount, "EMPTY") //TODO: NE KÉRJÜK LE DB-BŐL!!! - J. - { - ProductName = product.Name, - CurrentPrice = productToAuction.CurrentPrice, - NextStepAmount = stepAmount, - NextBidPrice = nextBidPrice, - }.ToJson() - }; + ProductName = product.Name, + CurrentPrice = productToAuction.CurrentPrice, + NextStepAmount = stepAmount, + NextBidPrice = nextBidPrice, + }.ToJson(); - await hubContext.Clients.All.SendAsync("send", bidMessage.ToJson()); + await SendMessageToClientsAsync(messageWrapper, sendToCaller); + } + + private async Task StepNextProductToAuctionAsync(MessageWrapper messageWrapper, Customer customer, ProductToAuctionMapping productToAuction, AuctionProductStatusRequest auctionProductStatusRequest) + { + var nextProductToAuction = await auctionService.GetNextProductToAuctionByAuctionIdAsync(productToAuction.AuctionId); + if (nextProductToAuction == null) return; + + await logger.InformationAsync($"SignalRMessageHandler.StepNextProductToAuctionAsync(); NextProductToAuctionId: {nextProductToAuction.Id};", null, customer); + + if (nextProductToAuction.AuctionStatus != AuctionStatus.None) + { + await logger.WarningAsync($"SignalRMessageHandler.StepNextProductToAuctionAsync(); (nextProductToAuction.AuctionStatus != AuctionStatus.None); NextProductToAuctionId: {nextProductToAuction.Id}; Status: {nextProductToAuction.AuctionStatus}({(int)nextProductToAuction.AuctionStatus})", null, customer); + return; //TODO: Ilyenkor mi legyen?! - J. + } + + auctionProductStatusRequest.AuctionStatus = AuctionStatus.Active; + auctionProductStatusRequest.ProductToAuctionId = nextProductToAuction.Id; + + await HandleProductToAuctionStatusChangedRequest(customer, messageWrapper); } private async Task ResetProductToAuction(ProductToAuctionMapping productToAuction, int? categoryId = null)