LMSPro.AspNetCore.SignalR
10.4.0
dotnet add package LMSPro.AspNetCore.SignalR --version 10.4.0
NuGet\Install-Package LMSPro.AspNetCore.SignalR -Version 10.4.0
<PackageReference Include="LMSPro.AspNetCore.SignalR" Version="10.4.0" />
<PackageVersion Include="LMSPro.AspNetCore.SignalR" Version="10.4.0" />
<PackageReference Include="LMSPro.AspNetCore.SignalR" />
paket add LMSPro.AspNetCore.SignalR --version 10.4.0
#r "nuget: LMSPro.AspNetCore.SignalR, 10.4.0"
#:package LMSPro.AspNetCore.SignalR@10.4.0
#addin nuget:?package=LMSPro.AspNetCore.SignalR&version=10.4.0
#tool nuget:?package=LMSPro.AspNetCore.SignalR&version=10.4.0
Lms.AspNetCore.SignalR
A comprehensive SignalR integration package for ASP.NET Core applications built on the LMS framework. This package provides real-time communication capabilities with seamless integration into the LMS ecosystem, including notifications, online client management, and hub-based messaging.
Features
🔄 Real-Time Communication
- SignalR hub integration with LMS framework
- Real-time notifications and messaging
- Bidirectional client-server communication
- Connection lifecycle management
📢 Notification System
- Real-time notification delivery via SignalR
- Integration with LMS notification infrastructure
- Multi-user notification broadcasting
- Automatic client targeting
👥 Online Client Management
- Track online users and connections
- Client information provider with IP tracking
- Multi-tenant client isolation
- Connection state management
🏗️ Hub Architecture
- Base hub classes for common functionality
- Extensible hub framework
- Dependency injection support
- Localization and session integration
🛡️ Security & Session
- User authentication integration
- Session management support
- Tenant-aware connections
- Secure connection handling
Installation
Package Manager
Install-Package LMSPro.AspNetCore.SignalR
.NET CLI
dotnet add package LMSPro.AspNetCore.SignalR
PackageReference
<PackageReference Include="LMSPro.AspNetCore.SignalR" Version="latest" />
Quick Start
1. Module Registration
[DependsOn(
typeof(LmsAspNetCoreModule),
typeof(LmsAspNetCoreSignalRModule)
)]
public class YourApplicationModule : LmsModule
{
// Module configuration
}
2. Startup Configuration
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Add SignalR services
services.AddSignalR();
// Configure LMS services
services.AddLms<YourApplicationModule>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Configure SignalR hub
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<LmsCommonHub>("/signalr");
});
}
}
3. Basic Hub Usage
public class ChatHub : LmsHubBase
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
public async Task JoinGroup(string groupName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
await Clients.Group(groupName).SendAsync("UserJoined", Context.User.Identity.Name);
}
}
Advanced Usage
Custom Hub Implementation
public class CustomHub : OnlineClientHubBase
{
public CustomHub(
IOnlineClientManager onlineClientManager,
IOnlineClientInfoProvider clientInfoProvider)
: base(onlineClientManager, clientInfoProvider)
{
}
public async Task SendToUser(long userId, string message)
{
var onlineClients = await OnlineClientManager.GetAllByUserIdAsync(
new UserIdentifier(LmsSession.TenantId, userId));
foreach (var client in onlineClients)
{
await Clients.Client(client.ConnectionId)
.SendAsync("ReceiveMessage", message);
}
}
public async Task BroadcastToTenant(string message)
{
var tenantId = Context.GetTenantId();
var clients = await OnlineClientManager.GetAllByTenantIdAsync(tenantId);
foreach (var client in clients)
{
await Clients.Client(client.ConnectionId)
.SendAsync("TenantBroadcast", message);
}
}
}
Real-Time Notifications
public class NotificationService : ITransientDependency
{
private readonly INotificationPublisher _notificationPublisher;
public NotificationService(INotificationPublisher notificationPublisher)
{
_notificationPublisher = notificationPublisher;
}
public async Task SendWelcomeNotificationAsync(UserIdentifier user)
{
await _notificationPublisher.PublishAsync(
"WelcomeNotification",
new MessageNotificationData("Welcome to our application!"),
userIds: new[] { user }
);
}
public async Task SendSystemAnnouncementAsync(string message)
{
await _notificationPublisher.PublishAsync(
"SystemAnnouncement",
new MessageNotificationData(message),
severity: NotificationSeverity.Info
);
}
}
Client-Side Integration
// JavaScript client setup
const connection = new signalR.HubConnectionBuilder()
.withUrl("/signalr")
.build();
// Start connection
connection.start().then(function () {
console.log("SignalR Connected");
// Register client
connection.invoke("Register");
}).catch(function (err) {
console.error(err.toString());
});
// Listen for notifications
connection.on("getNotification", function (notification) {
console.log("Received notification:", notification);
displayNotification(notification);
});
// Listen for messages
connection.on("ReceiveMessage", function (user, message) {
console.log(`${user}: ${message}`);
});
Multi-Tenant Hub
public class TenantAwareHub : OnlineClientHubBase
{
public TenantAwareHub(
IOnlineClientManager onlineClientManager,
IOnlineClientInfoProvider clientInfoProvider)
: base(onlineClientManager, clientInfoProvider)
{
}
public override async Task OnConnectedAsync()
{
await base.OnConnectedAsync();
var tenantId = Context.GetTenantId();
if (tenantId.HasValue)
{
await Groups.AddToGroupAsync(Context.ConnectionId, $"Tenant_{tenantId}");
}
}
public async Task SendToTenant(string message)
{
var tenantId = Context.GetTenantId();
if (tenantId.HasValue)
{
await Clients.Group($"Tenant_{tenantId}")
.SendAsync("TenantMessage", message);
}
}
}
Custom Online Client Provider
public class CustomOnlineClientInfoProvider : IOnlineClientInfoProvider
{
private readonly IClientInfoProvider _clientInfoProvider;
private readonly IUserManager _userManager;
public CustomOnlineClientInfoProvider(
IClientInfoProvider clientInfoProvider,
IUserManager userManager)
{
_clientInfoProvider = clientInfoProvider;
_userManager = userManager;
}
public IOnlineClient CreateClientForCurrentConnection(HubCallerContext context)
{
var userId = context.GetUserIdOrNull();
var tenantId = context.GetTenantId();
return new OnlineClient(
context.ConnectionId,
GetClientIpAddress(context),
tenantId,
userId)
{
ConnectTime = Clock.Now,
Properties = GetClientProperties(context)
};
}
private Dictionary<string, object> GetClientProperties(HubCallerContext context)
{
return new Dictionary<string, object>
{
["UserAgent"] = context.GetHttpContext()?.Request.Headers["User-Agent"].ToString(),
["Browser"] = GetBrowserInfo(context),
["Platform"] = GetPlatformInfo(context)
};
}
}
Hub with Localization
public class LocalizedHub : LmsHubBase
{
protected override string LocalizationSourceName { get; set; } = "MyApp";
public async Task SendLocalizedMessage(string messageKey)
{
var localizedMessage = L(messageKey);
await Clients.Caller.SendAsync("ReceiveMessage", localizedMessage);
}
public async Task SendLocalizedNotification(string notificationKey, params object[] args)
{
var message = L(notificationKey, args);
await Clients.Caller.SendAsync("ShowNotification", message);
}
}
Configuration Options
SignalR Configuration
services.AddSignalR(options =>
{
options.EnableDetailedErrors = true;
options.KeepAliveInterval = TimeSpan.FromSeconds(15);
options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
options.HandshakeTimeout = TimeSpan.FromSeconds(15);
});
Online Client Manager Configuration
services.Configure<LmsRealTimeOptions>(options =>
{
options.OnlineClientTimeout = TimeSpan.FromMinutes(30);
options.OnlineClientCleanupPeriod = TimeSpan.FromMinutes(5);
});
Custom Hub Registration
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<LmsCommonHub>("/signalr");
endpoints.MapHub<ChatHub>("/chathub");
endpoints.MapHub<NotificationHub>("/notifications");
});
Key Components
Hub Classes
- LmsHubBase: Base hub with LMS framework integration
- OnlineClientHubBase: Hub with online client management
- LmsCommonHub: Default hub for general-purpose communication
Notification System
- SignalRRealTimeNotifier: Real-time notification delivery
- IOnlineClientManager: Online client tracking and management
- IOnlineClientInfoProvider: Client information extraction
Extensions
- HubCallerContextExtensions: Context helper methods
- OnlineClientInfoProvider: Default client info implementation
Best Practices
Connection Management
public class RobustHub : OnlineClientHubBase
{
public override async Task OnConnectedAsync()
{
try
{
await base.OnConnectedAsync();
Logger.Info($"Client connected: {Context.ConnectionId}");
}
catch (Exception ex)
{
Logger.Error("Error during connection", ex);
throw;
}
}
public override async Task OnDisconnectedAsync(Exception exception)
{
try
{
await base.OnDisconnectedAsync(exception);
Logger.Info($"Client disconnected: {Context.ConnectionId}");
}
catch (Exception ex)
{
Logger.Error("Error during disconnection", ex);
}
}
}
Error Handling
public async Task SafeSendMessage(string message)
{
try
{
await Clients.All.SendAsync("ReceiveMessage", message);
}
catch (Exception ex)
{
Logger.Error($"Failed to send message: {message}", ex);
await Clients.Caller.SendAsync("Error", "Failed to send message");
}
}
Performance Optimization
// Use groups for efficient broadcasting
public async Task JoinTenantGroup()
{
var tenantId = Context.GetTenantId();
if (tenantId.HasValue)
{
await Groups.AddToGroupAsync(Context.ConnectionId, $"Tenant_{tenantId}");
}
}
// Batch operations when possible
public async Task SendBulkNotifications(List<UserNotification> notifications)
{
var tasks = notifications.Select(async notification =>
{
var clients = await OnlineClientManager.GetAllByUserIdAsync(notification.UserId);
return clients.Select(client =>
Clients.Client(client.ConnectionId).SendAsync("getNotification", notification));
}).SelectMany(x => await x);
await Task.WhenAll(tasks);
}
Security
[Authorize]
public class SecureHub : LmsHubBase
{
public async Task SendSecureMessage(string message)
{
// Verify user permissions
if (!await PermissionChecker.IsGrantedAsync("SendMessages"))
{
await Clients.Caller.SendAsync("Error", "Insufficient permissions");
return;
}
await Clients.All.SendAsync("ReceiveMessage", Context.User.Identity.Name, message);
}
}
Related Packages
- Lms: Core LMS framework
- Lms.AspNetCore: ASP.NET Core integration
- Lms.Notifications: Notification system
- Lms.RealTime: Real-time infrastructure
Documentation
Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Setup
- Clone the repository
- Install .NET 9.0 SDK
- Run
dotnet restore - Run
dotnet build
Running Tests
dotnet test
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- 📧 Email: support@lmsframework.com
- 💬 Community: LMS Framework Community
- 🐛 Issues: GitHub Issues
- 📖 Documentation: Official Docs
Statistics
LMS Framework - Building enterprise applications with ease 🚀
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- Lms (>= 10.4.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.4.0 | 193 | 8/18/2025 |