diff --git a/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js b/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js index eb5abb4..ad64e21 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js +++ b/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js @@ -1,6 +1,6 @@ $(function () { console.log("signalRJs Starts"); - + window.RequestCount = 1; // AuctionStatus Enum window.AuctionStatus = Object.freeze({ None: 0, @@ -46,17 +46,22 @@ // Global function to send a message to the server window.sendMessageToServer = function (messageType, senderId, data) { + window.RequestCount++; var messageWrapper = { MessageType: messageType, SenderId: senderId, + RequestCount: window.RequestCount, Data: data }; + console.log("Before send message to the server." + messageType); + connection.invoke("ReceiveMessageFromClient", messageWrapper) .then(() => { console.log("Message successfully sent to the server."); }) .catch(err => { + window.RequestCount--; console.error("Error sending message to the server:", err); }); }; diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs index 193bb01..2fcd446 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs @@ -13,50 +13,53 @@ using Nop.Plugin.Misc.AuctionPlugin.Services; using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities; using Newtonsoft.Json.Linq; using static LinqToDB.Reflection.Methods.LinqToDB.Insert; +using Mango.Nop.Services; namespace Nop.Plugin.Misc.AuctionPlugin.Hubs { - public class AuctionHub : Hub + public class AuctionHub(SessionService sessionService, ILogger logger, SignalRMessageHandler signalRMessageHandler) + : Hub { - private readonly SignalRMessageHandler _signalRMessageHandler; - - private readonly ILogger _logger; //HubCallerContext _hubCallerContext; - public AuctionHub(ILogger logger, SignalRMessageHandler signalRMessageHandler) - { - _logger = logger; - _signalRMessageHandler = signalRMessageHandler; - } - public override async Task OnConnectedAsync() { var connectionId = Context.ConnectionId; + //if (sessionService.GetOrCreateSessionItem(connectionId) == null) await logger.ErrorAsync($"AuctionHub.OnConnectedAsync(); (sessionItem == null); connectionId: {connectionId}"); + //await _logger.InformationAsync($"AuctionHub.OnConnectedAsync(); Caller connected with id: {connectionId}"); var httpContext = Context.GetHttpContext(); - if (httpContext == null) - { - await _logger.WarningAsync($"AuctionHub.OnConnectedAsync(); (httpContext == null); connectionId: {connectionId}"); - } + if (httpContext == null) await logger.ErrorAsync($"AuctionHub.OnConnectedAsync(); (httpContext == null); connectionId: {connectionId}"); else { + 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"]; if (!string.IsNullOrEmpty(userName)) { - await _logger.InformationAsync($"AuctionHub.OnConnectedAsync(); Caller connected with name: {userName}; connectionId: {connectionId}"); + await logger.InformationAsync($"AuctionHub.OnConnectedAsync(); Caller connected with name: {userName}; connectionId: {connectionId}"); } } await base.OnConnectedAsync(); } + public override Task OnDisconnectedAsync(Exception exception) + { + sessionService.TryRemoveSessionItem(Context.ConnectionId, out _); + + return base.OnDisconnectedAsync(exception); + } + public async Task ReceiveRegularMessageFromClient(string message) { //await _logger.InformationAsync($"AuctionHub.OnConnectedAsync(); message: {message}"); + if (sessionService.TryGetSessionItem(Context.GetHttpContext().Session.Id, out var sessionItem)) sessionItem.RequestCount++; + Console.WriteLine($"Received message: {message}"); await Clients.All.SendAsync("Send", message); } @@ -66,7 +69,9 @@ 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, Context.ConnectionId); + if (sessionService.TryGetSessionItem(Context.GetHttpContext().Session.Id, out var sessionItem)) sessionItem.RequestCount++; + + await signalRMessageHandler.HandleMessage(message, sessionItem, Context.ConnectionId); } } } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageWrapper.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageWrapper.cs index cc634b0..a99d255 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageWrapper.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageWrapper.cs @@ -11,7 +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 string RequestId { get; set; } + public int RequestCount { 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 bd341f5..fd83c38 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs @@ -1,5 +1,6 @@ using AyCode.Core.Extensions; using AyCode.Utils.Extensions; +using Mango.Nop.Services; using Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages; using Nop.Plugin.Misc.AuctionPlugin.Services; using Nop.Services.Catalog; @@ -30,9 +31,10 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs { private readonly Mutex _handleMessageMutex = new(); - public async Task HandleMessage(MessageWrapper messageWrapper, string connectionId) + public async Task HandleMessage(MessageWrapper messageWrapper, SessionItem sessionItem, string connectionId) { var customer = await workContext.GetCurrentCustomerAsync(); + //var connectionId = sessionItem?.SessionId; if (messageWrapper?.Data == null) { @@ -40,6 +42,9 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs 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 (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); @@ -139,7 +144,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs if (auctionProductStatusRequest == null) { logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); auctionProductStatusRequest == null", null, customer); - return ResponseType.Error;; + return ResponseType.Error; } try @@ -151,14 +156,14 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs if (productToAuction == null) { logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (productToAuction == null)", null, customer); - return ResponseType.Error;; + 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 ResponseType.Error;; + return ResponseType.Error; } if (!IsValidRequestAuctionStatus(auctionProductStatusRequest.AuctionStatus, productToAuction.AuctionStatus)) @@ -208,7 +213,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs default: logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); AuctionStatus not found; (auctionProductStatusRequest.AuctionStatus == {auctionProductStatusRequest.AuctionStatus})", null, customer); - return ResponseType.Error;; + return ResponseType.Error; } await auctionService.UpdateProductToAuctionMappingAsync(productToAuction); @@ -253,7 +258,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs if (bidRequestMessage == null) { logger.Error($"SignalRMessageHandler.HandleBidRequest(); (bidRequestMessage == null)", null, customer); - return ResponseType.Error;; + return ResponseType.Error; } try @@ -264,11 +269,11 @@ 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 ResponseType.Error;; + return ResponseType.Error; } var product = await auctionService.GetProductById(bidRequestMessage.ProductId); - if (product == null) return ResponseType.Error;; + 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))) diff --git a/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/PluginNopStartup.cs b/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/PluginNopStartup.cs index 8081ffe..0e63790 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/PluginNopStartup.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/PluginNopStartup.cs @@ -43,6 +43,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Infrastructure options.ViewLocationExpanders.Add(new ViewLocationExpander()); }); + services.AddSingleton(); services.AddSignalR(hubOptions => { hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(1); diff --git a/Nop.Plugin.Misc.AuctionPlugin/Nop.Plugin.Misc.AuctionPlugin.csproj b/Nop.Plugin.Misc.AuctionPlugin/Nop.Plugin.Misc.AuctionPlugin.csproj index 384c49a..2f0edb8 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Nop.Plugin.Misc.AuctionPlugin.csproj +++ b/Nop.Plugin.Misc.AuctionPlugin/Nop.Plugin.Misc.AuctionPlugin.csproj @@ -10,6 +10,7 @@ true true enable + latest diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/ISessionItem.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/ISessionItem.cs new file mode 100644 index 0000000..213a488 --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/ISessionItem.cs @@ -0,0 +1,8 @@ +using Mango.Nop.Services; + +namespace Nop.Plugin.Misc.AuctionPlugin.Services; + +public interface ISessionItem : IMgSessionItem +{ + +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/ISessionService.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/ISessionService.cs new file mode 100644 index 0000000..3f72369 --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/ISessionService.cs @@ -0,0 +1,8 @@ +using Mango.Nop.Services; + +namespace Nop.Plugin.Misc.AuctionPlugin.Services; + +public interface ISessionService : IMgSessionService +{ + +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/SessionItem.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/SessionItem.cs new file mode 100644 index 0000000..737cfbd --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/SessionItem.cs @@ -0,0 +1,8 @@ +using Mango.Nop.Services; + +namespace Nop.Plugin.Misc.AuctionPlugin.Services; + +public class SessionItem(string sessionKey) : MgSessionItem(sessionKey), ISessionItem +{ + +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/SessionService.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/SessionService.cs new file mode 100644 index 0000000..374ed63 --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/SessionService.cs @@ -0,0 +1,8 @@ +using Mango.Nop.Services; + +namespace Nop.Plugin.Misc.AuctionPlugin.Services; + +public class SessionService : MgSessionService, ISessionService +{ + +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.SignalRApi/Controllers/SignalRApiController.cs b/Nop.Plugin.Misc.SignalRApi/Controllers/SignalRApiController.cs index 96a0eae..878dbcc 100644 --- a/Nop.Plugin.Misc.SignalRApi/Controllers/SignalRApiController.cs +++ b/Nop.Plugin.Misc.SignalRApi/Controllers/SignalRApiController.cs @@ -21,7 +21,7 @@ namespace Nop.Plugin.Misc.SignalRApi.Controllers offers.Add("20% Off on IPhone 12"); offers.Add("15% Off on HP Pavillion"); offers.Add("25% Off on Samsung Smart TV"); - mainHub.Clients.All.SendOffersToUser(offers); + //mainHub.Clients.All.SendOffersToUser(offers); return "Offers sent successfully to all users!"; } } diff --git a/Nop.Plugin.Misc.SignalRApi/Infrastructure/PluginNopStartup.cs b/Nop.Plugin.Misc.SignalRApi/Infrastructure/PluginNopStartup.cs index 7bd7266..3c38d86 100644 --- a/Nop.Plugin.Misc.SignalRApi/Infrastructure/PluginNopStartup.cs +++ b/Nop.Plugin.Misc.SignalRApi/Infrastructure/PluginNopStartup.cs @@ -40,13 +40,13 @@ namespace Nop.Plugin.Misc.SignalRApi.Infrastructure /// Builder for configuring an application's request pipeline public void Configure(IApplicationBuilder application) { - application.UseEndpoints(endpoints => - { - endpoints.MapHub("/mainHub"); - }); - application.UseCors(options => { - options.AllowAnyMethod().AllowAnyHeader().AllowCredentials().SetIsOriginAllowed((hosts) => true); - }); + //application.UseEndpoints(endpoints => + //{ + // endpoints.MapHub("/mainHub"); + //}); + //application.UseCors(options => { + // options.AllowAnyMethod().AllowAnyHeader().AllowCredentials().SetIsOriginAllowed((hosts) => true); + //}); }