Mango.Nop.Plugins/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs

189 lines
7.7 KiB
C#

using System.Globalization;
using AyCode.Core.Extensions;
using Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages;
using Newtonsoft.Json.Linq;
using Nop.Plugin.Misc.AuctionPlugin.Models;
using Nop.Plugin.Misc.AuctionPlugin.Services;
using Nop.Services.Catalog;
using Newtonsoft.Json;
using Nop.Services.Logging;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities;
using Newtonsoft.Json.Serialization;
using Microsoft.AspNetCore.SignalR;
using Nop.Core;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums;
using MimeKit;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities.Interfaces;
namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
{
public class SignalRMessageHandler
{
protected readonly ILogger _logger;
protected readonly IProductService _productService;
protected readonly AuctionService _auctionService;
private IHubContext<AuctionHub> _hubContext;
private readonly IWorkContext _workContext;
public SignalRMessageHandler(ILogger logger, IProductService productService, AuctionService auctionService, IHubContext<AuctionHub> hubContext, IWorkContext workContext)
{
_logger = logger;
_productService = productService;
_auctionService = auctionService;
_hubContext = hubContext;
_workContext = workContext;
}
public async Task HandleMessage(MessageWrapper message)
{
if (message?.Data == null)
{
_logger.Error($"SignalRMessageHandler.HandleMessage(); message?.Data == null");
return;
}
//TODO: A MessageWrapper-ben kéne küldözgetni a UserId (CustomerId-t) - J.
//if (message.UserId != (await _workContext.GetCurrentCustomerAsync()).Id)
//{
// _logger.Error($"SignalRMessageHandler.HandleMessage(); message.UserId != (await _workContext.GetCurrentCustomerAsync()).Id");
// return;
//}
switch (message.MessageType)
{
case "BidRequestMessage":
await HandleBidRequest(message.SenderId, message.Data.JsonTo<AuctionBidRequest>());
break;
case "OpenItemRequestMessage":
await HandleOpenItemMessageRequest(message.SenderId, message.Data.JsonTo<OpenItemRequest>());
break;
// Add other message types here
default:
await _logger.ErrorAsync("SignalRMessageHandler.HandleMessage(); Unknown message type");
break;
}
}
private async Task HandleOpenItemMessageRequest(int senderId, OpenItemRequest openItemMessage)
{
if (openItemMessage == null)
{
_logger.Error($"SignalRMessageHandler.HandleOpenItemMessageRequest(); openItemRequestMessage == null");
return;
}
try
{
await _logger.InformationAsync($"SignalRMessageHandler.HandleOpenItemMessageRequest(); Item to open: - ProductToAuctionMappingId: {openItemMessage.ProductAuctionMappingId}");
//get auction
var auction = await _auctionService.GetAuctionDtoByProductToAuctionIdAsync(openItemMessage.ProductAuctionMappingId);
//get productToAuction
var productToAuction = await _auctionService.GetProductToAuctionDtoByIdAsync(openItemMessage.ProductAuctionMappingId);
auction.Closed = false;
await _logger.InformationAsync($"SignalRMessageHandler.HandleOpenItemMessageRequest(); Auction {auction.Id}, ProducToAuction {productToAuction.Id}");
//_auctionService.UpdateAuctionAsync(auction);
var notification = new AuctionUpdateNotificationMessage
{
AuctionId = auction.Id,
};
var bid = new MessageWrapper
{
MessageType = "auctionEventNotification",
SenderId = senderId,
Data = notification.ToJson()
};
//await _hubContext.Clients.All.SendAsync("send", bid.ToJson());
}
catch (Exception ex)
{
_logger.Error($"Error {ex.Message}");
}
}
private async Task HandleBidRequest(int senderId, AuctionBidRequest bidRequestMessage)
{
if (bidRequestMessage == null)
{
_logger.Error($"SignalRMessageHandler.HandleBidRequest(); bidRequestMessage == null");
return;
}
try
{
await _logger.InformationAsync($"SignalRMessageHandler.HandleBidRequest(); Bid received: - Auction: {bidRequestMessage.AuctionId} Product: {bidRequestMessage.ProductId} - Bid: {bidRequestMessage.BidPrice} - Customer: {bidRequestMessage.CustomerId}");
if (bidRequestMessage.CustomerId != (await _workContext.GetCurrentCustomerAsync()).Id)
{
_logger.Error($"SignalRMessageHandler.HandleBidRequest(); bidRequestMessage.CustomerId != (await _workContext.GetCurrentCustomerAsync()).Id");
return;
}
var product = await _productService.GetProductByIdAsync(bidRequestMessage.ProductId);
if (product == null)
{
_logger.Error($"SignalRMessageHandler.HandleBidRequest(); product == null");
return; //ha nincs product vagy exception van, akkor ne broadcast-eljük ki az invalid Bid-et! - J.
}
var mapping = await _auctionService.GetProductToAuctionByAuctionIdAndProductIdAsync(bidRequestMessage.AuctionId, bidRequestMessage.ProductId);
if (mapping == null || mapping.Count == 0)
{
_logger.Error($"SignalRMessageHandler.HandleBidRequest(); mapping == null || mapping.Count == 0");
return; //ha nincs ProductToAuction, akkor ne broadcast-eljük ki az invalid Bid-et! - J.
}
var auctionBid = bidRequestMessage.CreateMainEntity();
auctionBid.ProductAuctionMappingId = mapping.FirstOrDefault()!.Id;
//TODO: validate the bidprice amount
if (product.Price >= auctionBid.BidPrice)
{
_logger.Warning($"SignalRMessageHandler.HandleBidRequest(); product.Price >= bidRequestMessage.BidPrice; productPrice: {product.Price}; bidRequestPrice: {auctionBid.BidPrice}");
return;
}
//save bid
await _auctionService.InsertBidAsync(auctionBid);
//set new price
product.Price = bidRequestMessage.BidPrice;
await _productService.UpdateProductAsync(product);
// Optionally broadcast to all clients
var bid = new MessageWrapper
{
MessageType = "bidNotification",
SenderId = senderId,
Data = new BidNotificationMessage
{
ProductName = auctionBid.ProductId.ToString(),
BidPrice = auctionBid.BidPrice.ToString(CultureInfo.InvariantCulture),
NextStepAmount = "50000"
}.ToJson()
};
await _hubContext.Clients.All.SendAsync("send", bid.ToJson());
}
catch (Exception ex)
{
_logger.Error($"SignalRMessageHandler.HandleBidRequest(); MessageHandling error: {ex}");
}
}
}
}