mirror of
https://github.com/yawaflua/WebSockets.git
synced 2025-12-08 19:39:30 +02:00
develop
Replaces `Dictionary` with `ConcurrentDictionary` for thread-safe WebSocket route management and improves error logging with added debug assertions. Also fixes duplicate registrations, enhances dependency injection, updates package references, and adjusts WebSocket attribute structure for better extensibility and usage.
New WebSocket routing system
Features
- ASP.NET Core-style WebSocket routing 🛣️
- Method-based endpoint handlers (Like in ASP!) 🎯
- Simple integration with existing applications ⚡
Installation
Add the NuGet package to your project:
dotnet add package yawaflua.WebSockets
Quick Start
1. Create WebSocket Controller
public class ChatController : WebSocketController
{
[WebSocket("/chat")]
public override async Task OnMessageAsync(
IWebSocket webSocket,
HttpContext httpContext)
{
await webSocket.SendAsync("Message!");
}
}
2. Configure Services
public void ConfigureServices(IServiceCollection services)
{
services
.AddControllers()
.SettingUpWebSockets(); // ← Add WebSocket routing
services.AddSingleton<ChatController>();
}
3. Enable Middleware
public void Configure(IApplicationBuilder app)
{
app.ConnectWebSockets(); // ← Add WebSocket handling
app.UseRouting();
app.UseEndpoints(endpoints => endpoints.MapControllers());
}
Advanced Usage
Parameterized Routes
public class NotificationsController : WebSocketController
{
[WebSocket("/notifications/{userId}")]
public override async Task OnMessageAsync(
IWebSocket webSocket,
HttpContext httpContext)
{
var userId = httpContext.Request.RouteValues["userId"];
// Handle user-specific notifications
}
}
Method-Level Routes
[WebSocket("/game")]
public class GameController : WebSocketController
{
[WebSocket("join/{roomId}")]
public async Task JoinRoom(IWebSocket webSocket, HttpContext context)
{
// Handle room joining
}
[WebSocket("leave/{roomId}")]
public async Task LeaveRoom(IWebSocket webSocket, HttpContext context)
{
// Handle room leaving
}
}
Providing dependencies in controller
[WebSocket("/chat")]
public class ChatController : WebSocketController
{
public static DbContext dbContext;
public ChatController(DbContext dbContext)
{
ChatController.dbContext = dbContext;
}
[WebSocket("join/{roomId}")]
public async Task JoinRoom(WebSocket webSocket, HttpContext context)
{
await dbContext.Add(...);
// Next your logic etc
}
[WebSocket("leave/{roomId}")]
public async Task LeaveRoom(WebSocket webSocket, HttpContext context)
{
// Handle room leaving
}
}
Run any code on connection to WebSocket
services.AddSingleton(new WebSocketConfig()
{
OnOpenHandler = async (socket, context) =>
{
if (socket.WebSocketManager!.GetAllClients().Count(k =>
Equals(k.ConnectionInfo!.RemoteIpAddress!.MapToIPv4(),
socket.Client.ConnectionInfo!.RemoteIpAddress!.MapToIPv4())) >= 3)
{
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Too many users");
}
Console.WriteLine($"{socket.Client.Id} has been connected to {socket.Client.Path}");
}
})
Work with c=connected users from any point at your code!
public class MyCoolService
{
private IWebSocketManager _manager;
public MyCoolService(IWebSocketManager manager)
{
_manager = manager;
}
public async Task DoSomething()
{
await _manager.Broadcast(k => k.Path == "/my/cool/endpoint", "Hello!");
}
}
// DependencyInjection should provide IWebSocketManager to builder
services.AddSingleton<MyCoolService>();
Lifecycle Management
- Connection - Automatically handled by middleware
- Message Handling - Implement
OnMessageAsync - Cleanup - Dispose resources in
IDisposableinterface
Best Practices
- Keep Controllers Light - Move business logic to services
- Use Dependency Injection - Inject services via constructor
- Handle Exceptions - Wrap operations in try/catch blocks
- Manage State - Use
HttpContext.Itemsfor request-scoped data
Troubleshooting
No Route Handling?
- Verify controller registration in DI:
services.AddSingleton<YourController>();
Connection Issues?
- Ensure middleware order:
app.ConnectWebSockets(); // Must be before UseRouting/UseEndpoints
Parameters Not Working?
- Check route template syntax:
[WebSocket("/correct/{paramName}")] // ✓ [WebSocket("/wrong/{param-name}")] // ✗
License
Description
Languages
C#
100%