Added ASP.NET Core SignalR feature to eShopOnContainers (Real time push notifications on Order's status)
CESARDELATORRE opened this issue · comments
In the current code of DEV branch we have added a new feature using ASP.NET Core SignalR so whenever an Order changes its status, the eShop user/buyer is notified with a tool-tip in a "push" real-time fashion, as the following:
Of course, you will also see it if you are positioned on the Orders page:
This ASP.NET Core SignalR Hub service was added as part of the Ordering "Business Microservice" or Ordering Bounded Context (BC) pattern, as shown in VS Explorer screenshot:
Here's the SignalR Hub code:
namespace Ordering.SignalrHub
{
[Authorize]
public class NotificationsHub : Hub
{
public override async Task OnConnectedAsync()
{
await Groups.AddAsync(Context.ConnectionId, Context.User.Identity.Name);
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception ex)
{
await Groups.RemoveAsync(Context.ConnectionId, Context.User.Identity.Name);
await base.OnDisconnectedAsync(ex);
}
}
}
It is using Redis to store its configuration so it can scale-out to multiple instances of the SignalR Hub service when deploying to an orchestrator like Kubernetes/AKS.
Another interesting functionality is the integration between the SignalR Hub service and the microservices' Integration Events, showing how the SignalR Hub is subscribed to those events through our Event Bus (depending on the selected implementation, based on RabbitMQ or Azure Service Bus), so it is waiting for Order's changes/events and pushing them to SignalR clients to show the order's status changes in those tool tips
Here's the code of one of those integration event-handlers. Check out how simple is to send a SignalR message:
public class OrderStatusChangedToPaidIntegrationEventHandler : IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent>
{
private readonly IHubContext<NotificationsHub> _hubContext;
public OrderStatusChangedToPaidIntegrationEventHandler(IHubContext<NotificationsHub> hubContext)
{
_hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
}
public async Task Handle(OrderStatusChangedToPaidIntegrationEvent @event)
{
await _hubContext.Clients
.Group(@event.BuyerName)
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
}
}