dotnet-architecture / News

News on .NET Architecture Guidance, eShopOnContainers and all the reference apps in dotnet-architecture
MIT License
1.1k stars 79 forks source link

Added ASP.NET Core SignalR feature to eShopOnContainers (Real time push notifications on Order's status) #16

Open CESARDELATORRE opened 6 years ago

CESARDELATORRE commented 6 years ago

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:

image

Of course, you will also see it if you are positioned on the Orders page:

image

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:

image

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

See the event handlers: image

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 });
        }
    }