Azure SignalR server-side implementation for NuvTools.Notification.Realtime. Provides AzureSignalRSender for broadcasting messages to all connected clients via SignalR hubs. Enables scalable, cloud-based real-time notifications with minimal configuration.
$ dotnet add package NuvTools.Notification.Realtime.Azure.SignalRA comprehensive set of modular .NET libraries for notification and messaging scenarios, including email, real-time communication, and cloud-based messaging with Azure Service Bus and SignalR.
NuvTools Notification Libraries provide a clean abstraction layer over various notification systems, allowing you to write code against interfaces and swap implementations without changing your business logic. The libraries follow the abstraction-implementation pattern, where core abstractions are separate from infrastructure-specific implementations.
NuvTools.Notification.Messaging
IMessageSender<TBody>, IMessageConsumer<TBody>, IMessageContextMessage<T> envelope with metadata (MessageId, CorrelationId, Subject, TimeToLive)NuvTools.Notification.Messaging.Azure.ServiceBus
AzureServiceBusReceiver<TBody, TConsumer>) for consuming messagesNuvTools.Notification.Mail
IMailService abstraction for sending emailsMailMessage, MailAddress, and MailPart modelsNuvTools.Notification.Mail.Smtp
MailConfigurationSectionNuvTools.Notification.Realtime
IMessageSender<T> abstraction for broadcasting messagesNuvTools.Notification.Realtime.Azure.SignalR
AzureSignalRSender<T>)SignalRHub registrationNuvTools.Notification.Realtime.Azure.SignalR.Client
AzureSignalRReceiver<T>)Install the packages you need via NuGet:
dotnet add package NuvTools.Notification.Messaging
dotnet add package NuvTools.Notification.Messaging.Azure.ServiceBus
dotnet add package NuvTools.Notification.Mail
dotnet add package NuvTools.Notification.Mail.Smtp
dotnet add package NuvTools.Notification.Realtime
dotnet add package NuvTools.Notification.Realtime.Azure.SignalR
dotnet add package NuvTools.Notification.Realtime.Azure.SignalR.Client
// Define your sender
public class OrderSender : AzureServiceBusSender<Order>
{
public OrderSender(IOptions<MessagingSection> options)
: base(options.Value) { }
}
// Send a message
var message = new Message<Order>(order)
{
Subject = "order.created",
CorrelationId = correlationId
};
await orderSender.SendAsync(message, cancellationToken);
// Define your consumer
public class OrderConsumer : IMessageConsumer<Order>
{
public async Task ConsumeAsync(Message<Order> message, IMessageContext context, CancellationToken cancellationToken)
{
// Process the order
await ProcessOrder(message.Body);
// Complete the message
await context.CompleteAsync(cancellationToken);
}
}
// Define your background receiver
public class OrderReceiver : AzureServiceBusReceiver<Order, OrderConsumer>
{
public OrderReceiver(ILogger<OrderReceiver> logger, IServiceProvider serviceProvider, IOptions<MessagingSection> options)
: base(logger, serviceProvider, options.Value) { }
}
var mailMessage = new MailMessage
{
From = new MailAddress { Address = "sender@example.com", DisplayName = "Support Team" },
To = new List<MailAddress> { new() { Address = "user@example.com", DisplayName = "John Doe" } },
Subject = "Welcome!",
Body = "<h1>Welcome to our service!</h1>"
};
await mailService.SendAsync(mailMessage);
Server-side:
// Broadcast a notification
var notification = new UserNotification { Message = "New order received", UserId = userId };
await signalRSender.SendAsync(notification, cancellationToken);
Client-side:
var receiver = new AzureSignalRReceiver<UserNotification>("https://yourapp.com/notificationHub");
receiver.MessageReceived += (notification, token) =>
{
Console.WriteLine($"Received: {notification.Message}");
};
await receiver.ConnectAsync();
// appsettings.json
{
"NuvTools.Notification.Messaging": {
"Name": "orders-queue",
"ConnectionString": "Endpoint=sb://...",
"MaxConcurrentCalls": 10,
"MaxAutoLockRenewalDuration": "00:30:00",
"AutoCompleteMessages": false
}
}
// Program.cs
services.AddMessagingQueueConfiguration<MessagingSection>(configuration);
services.AddSingleton<OrderSender>();
services.AddScoped<OrderConsumer>();
services.AddHostedService<OrderReceiver>();
using var fileStream = File.OpenRead("document.pdf");
var mailMessage = new MailMessage
{
From = new MailAddress { Address = "noreply@company.com" },
To = new List<MailAddress> { new() { Address = "customer@example.com" } },
Subject = "Your Invoice",
Body = "<p>Please find your invoice attached.</p>",
Parts = new List<MailPart>
{
new()
{
MediaType = "application",
MediaExtension = "pdf",
Content = fileStream
}
}
};
await mailService.SendAsync(mailMessage);
public class ResilientOrderConsumer : IMessageConsumer<Order>
{
public async Task ConsumeAsync(Message<Order> message, IMessageContext context, CancellationToken cancellationToken)
{
try
{
await ProcessOrder(message.Body);
await context.CompleteAsync(cancellationToken);
}
catch (ValidationException ex)
{
// Invalid message - send to dead letter queue
await context.DeadLetterAsync("ValidationFailed", ex.Message, cancellationToken);
}
catch (Exception ex)
{
// Transient error - abandon for retry
await context.AbandonAsync(cancellationToken);
}
}
}
{
"NuvTools.Notification.Mail": {
"From": "noreply@yourcompany.com",
"DisplayName": "Your Company",
"Host": "smtp.gmail.com",
"Port": 587,
"UserName": "your-email@gmail.com",
"Password": "your-app-password"
}
}
{
"NuvTools.Notification.Messaging": {
"Name": "my-queue",
"SubscriptionName": null,
"ConnectionString": "Endpoint=sb://namespace.servicebus.windows.net/;SharedAccessKeyName=...",
"MaxAutoLockRenewalDuration": "00:30:00",
"MaxConcurrentCalls": 10,
"AutoCompleteMessages": false
}
}
// Configure mail
services.AddMailConfiguration(configuration);
services.AddSingleton<IMailService, SMTPMailService>();
// Configure messaging
services.AddMessagingQueueConfiguration<MessagingSection>(configuration);
// Configure SignalR
services.AddSignalR();
services.AddSingleton<IMessageSender<Notification>, AzureSignalRSender<Notification>>();
// In your app configuration
app.MapHub<SignalRHub>("/notificationHub");
IMessageSender, IMailService)AzureServiceBusSender, SMTPMailService)Message<T> wraps your payload with common propertiesIMessageConsumer<TBody> handles incoming messagesIMessageContext manages message lifecycle (complete, abandon, dead-letter)Build the entire solution:
dotnet build NuvTools.Notification.slnx
Build in Release mode and generate NuGet packages:
dotnet build -c Release NuvTools.Notification.slnx
Restore packages:
dotnet restore NuvTools.Notification.slnx
Build a specific project:
dotnet build src/NuvTools.Notification.Messaging/NuvTools.Notification.Messaging.csproj
Clean build artifacts:
dotnet clean NuvTools.Notification.slnx
This project uses the modern .slnx (XML-based solution) format introduced in Visual Studio 2022, which provides:
dotnet CLIAll libraries target .NET 8, .NET 9, and .NET 10 for modern, high-performance applications.
Contributions are welcome! Please ensure:
Copyright © 2026 Nuv Tools. All rights reserved.