Implement SessionService, SessionItem; improvements, fixes, etc...

This commit is contained in:
Loretta 2024-12-04 19:13:56 +01:00
parent 99f60ad70d
commit 5ca7ad53f1
12 changed files with 84 additions and 34 deletions

View File

@ -1,6 +1,6 @@
$(function () { $(function () {
console.log("signalRJs Starts"); console.log("signalRJs Starts");
window.RequestCount = 1;
// AuctionStatus Enum // AuctionStatus Enum
window.AuctionStatus = Object.freeze({ window.AuctionStatus = Object.freeze({
None: 0, None: 0,
@ -46,17 +46,22 @@
// Global function to send a message to the server // Global function to send a message to the server
window.sendMessageToServer = function (messageType, senderId, data) { window.sendMessageToServer = function (messageType, senderId, data) {
window.RequestCount++;
var messageWrapper = { var messageWrapper = {
MessageType: messageType, MessageType: messageType,
SenderId: senderId, SenderId: senderId,
RequestCount: window.RequestCount,
Data: data Data: data
}; };
console.log("Before send message to the server." + messageType);
connection.invoke("ReceiveMessageFromClient", messageWrapper) connection.invoke("ReceiveMessageFromClient", messageWrapper)
.then(() => { .then(() => {
console.log("Message successfully sent to the server."); console.log("Message successfully sent to the server.");
}) })
.catch(err => { .catch(err => {
window.RequestCount--;
console.error("Error sending message to the server:", err); console.error("Error sending message to the server:", err);
}); });
}; };

View File

@ -13,50 +13,53 @@ using Nop.Plugin.Misc.AuctionPlugin.Services;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities; using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using static LinqToDB.Reflection.Methods.LinqToDB.Insert; using static LinqToDB.Reflection.Methods.LinqToDB.Insert;
using Mango.Nop.Services;
namespace Nop.Plugin.Misc.AuctionPlugin.Hubs namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
{ {
public class AuctionHub : Hub<IAuctionHubClient> public class AuctionHub(SessionService sessionService, ILogger logger, SignalRMessageHandler signalRMessageHandler)
: Hub<IAuctionHubClient>
{ {
private readonly SignalRMessageHandler _signalRMessageHandler;
private readonly ILogger _logger;
//HubCallerContext _hubCallerContext; //HubCallerContext _hubCallerContext;
public AuctionHub(ILogger logger, SignalRMessageHandler signalRMessageHandler)
{
_logger = logger;
_signalRMessageHandler = signalRMessageHandler;
}
public override async Task OnConnectedAsync() public override async Task OnConnectedAsync()
{ {
var connectionId = Context.ConnectionId; 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}"); //await _logger.InformationAsync($"AuctionHub.OnConnectedAsync(); Caller connected with id: {connectionId}");
var httpContext = Context.GetHttpContext(); var httpContext = Context.GetHttpContext();
if (httpContext == null) if (httpContext == null) await logger.ErrorAsync($"AuctionHub.OnConnectedAsync(); (httpContext == null); connectionId: {connectionId}");
{
await _logger.WarningAsync($"AuctionHub.OnConnectedAsync(); (httpContext == null); connectionId: {connectionId}");
}
else 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"]; var userName = httpContext.Request.Query["ConnectionId"];
if (!string.IsNullOrEmpty(userName)) 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(); await base.OnConnectedAsync();
} }
public override Task OnDisconnectedAsync(Exception exception)
{
sessionService.TryRemoveSessionItem(Context.ConnectionId, out _);
return base.OnDisconnectedAsync(exception);
}
public async Task ReceiveRegularMessageFromClient(string message) public async Task ReceiveRegularMessageFromClient(string message)
{ {
//await _logger.InformationAsync($"AuctionHub.OnConnectedAsync(); message: {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}"); Console.WriteLine($"Received message: {message}");
await Clients.All.SendAsync("Send", message); await Clients.All.SendAsync("Send", message);
} }
@ -66,7 +69,9 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
// Log the message type and data // Log the message type and data
//await _logger.InformationAsync($"AuctionHub.OnConnectedAsync(); Received message of type: {message.MessageType}"); //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);
} }
} }
} }

View File

@ -11,7 +11,8 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages
{ {
public string MessageType { get; set; } public string MessageType { get; set; }
public int SenderId { 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 ResponseType ResponseType { get; set; }
public string Data { get; set; } public string Data { get; set; }
} }

View File

@ -1,5 +1,6 @@
using AyCode.Core.Extensions; using AyCode.Core.Extensions;
using AyCode.Utils.Extensions; using AyCode.Utils.Extensions;
using Mango.Nop.Services;
using Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages; using Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages;
using Nop.Plugin.Misc.AuctionPlugin.Services; using Nop.Plugin.Misc.AuctionPlugin.Services;
using Nop.Services.Catalog; using Nop.Services.Catalog;
@ -30,9 +31,10 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
{ {
private readonly Mutex _handleMessageMutex = new(); 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 customer = await workContext.GetCurrentCustomerAsync();
//var connectionId = sessionItem?.SessionId;
if (messageWrapper?.Data == null) if (messageWrapper?.Data == null)
{ {
@ -40,6 +42,9 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
return; 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)) 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); 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) if (auctionProductStatusRequest == null)
{ {
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); auctionProductStatusRequest == null", null, customer); logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); auctionProductStatusRequest == null", null, customer);
return ResponseType.Error;; return ResponseType.Error;
} }
try try
@ -151,14 +156,14 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
if (productToAuction == null) if (productToAuction == null)
{ {
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (productToAuction == null)", null, customer); logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (productToAuction == null)", null, customer);
return ResponseType.Error;; return ResponseType.Error;
} }
var auction = await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId); var auction = await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId);
if (auction == null || auction.Closed) if (auction == null || auction.Closed)
{ {
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer); 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)) if (!IsValidRequestAuctionStatus(auctionProductStatusRequest.AuctionStatus, productToAuction.AuctionStatus))
@ -208,7 +213,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
default: default:
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); AuctionStatus not found; (auctionProductStatusRequest.AuctionStatus == {auctionProductStatusRequest.AuctionStatus})", null, customer); logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); AuctionStatus not found; (auctionProductStatusRequest.AuctionStatus == {auctionProductStatusRequest.AuctionStatus})", null, customer);
return ResponseType.Error;; return ResponseType.Error;
} }
await auctionService.UpdateProductToAuctionMappingAsync(productToAuction); await auctionService.UpdateProductToAuctionMappingAsync(productToAuction);
@ -253,7 +258,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
if (bidRequestMessage == null) if (bidRequestMessage == null)
{ {
logger.Error($"SignalRMessageHandler.HandleBidRequest(); (bidRequestMessage == null)", null, customer); logger.Error($"SignalRMessageHandler.HandleBidRequest(); (bidRequestMessage == null)", null, customer);
return ResponseType.Error;; return ResponseType.Error;
} }
try try
@ -264,11 +269,11 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
if (auction == null || auction.Closed) if (auction == null || auction.Closed)
{ {
logger.Warning($"SignalRMessageHandler.HandleBidRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer); 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); 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(); 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))) if (activeProductAuction is not { IsActiveItem: true } || (activeProductAuction.WinnerCustomerId == customer.Id && !await customerService.IsAdminAsync(customer)))

View File

@ -43,6 +43,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Infrastructure
options.ViewLocationExpanders.Add(new ViewLocationExpander()); options.ViewLocationExpanders.Add(new ViewLocationExpander());
}); });
services.AddSingleton<SessionService>();
services.AddSignalR(hubOptions => services.AddSignalR(hubOptions =>
{ {
hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(1); hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(1);

View File

@ -10,6 +10,7 @@
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<CopyRefAssembliesToPublishDirectory>true</CopyRefAssembliesToPublishDirectory> <CopyRefAssembliesToPublishDirectory>true</CopyRefAssembliesToPublishDirectory>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -0,0 +1,8 @@
using Mango.Nop.Services;
namespace Nop.Plugin.Misc.AuctionPlugin.Services;
public interface ISessionItem : IMgSessionItem
{
}

View File

@ -0,0 +1,8 @@
using Mango.Nop.Services;
namespace Nop.Plugin.Misc.AuctionPlugin.Services;
public interface ISessionService : IMgSessionService<SessionItem>
{
}

View File

@ -0,0 +1,8 @@
using Mango.Nop.Services;
namespace Nop.Plugin.Misc.AuctionPlugin.Services;
public class SessionItem(string sessionKey) : MgSessionItem(sessionKey), ISessionItem
{
}

View File

@ -0,0 +1,8 @@
using Mango.Nop.Services;
namespace Nop.Plugin.Misc.AuctionPlugin.Services;
public class SessionService : MgSessionService<SessionItem>, ISessionService
{
}

View File

@ -21,7 +21,7 @@ namespace Nop.Plugin.Misc.SignalRApi.Controllers
offers.Add("20% Off on IPhone 12"); offers.Add("20% Off on IPhone 12");
offers.Add("15% Off on HP Pavillion"); offers.Add("15% Off on HP Pavillion");
offers.Add("25% Off on Samsung Smart TV"); 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!"; return "Offers sent successfully to all users!";
} }
} }

View File

@ -40,13 +40,13 @@ namespace Nop.Plugin.Misc.SignalRApi.Infrastructure
/// <param name="application">Builder for configuring an application's request pipeline</param> /// <param name="application">Builder for configuring an application's request pipeline</param>
public void Configure(IApplicationBuilder application) public void Configure(IApplicationBuilder application)
{ {
application.UseEndpoints(endpoints => //application.UseEndpoints(endpoints =>
{ //{
endpoints.MapHub<MainHub>("/mainHub"); // endpoints.MapHub<MainHub>("/mainHub");
}); //});
application.UseCors(options => { //application.UseCors(options => {
options.AllowAnyMethod().AllowAnyHeader().AllowCredentials().SetIsOriginAllowed((hosts) => true); // options.AllowAnyMethod().AllowAnyHeader().AllowCredentials().SetIsOriginAllowed((hosts) => true);
}); //});
} }