adds comments, OOP incapsulation and publish package to nuget

This commit is contained in:
Dmitri Shimanski
2025-03-29 02:54:54 +03:00
parent 2ba9667a01
commit 1b1eb17bee
11 changed files with 103 additions and 19 deletions

View File

@@ -1,6 +1,6 @@
using yawaflua.WebSockets.Attributes;
using yawaflua.WebSockets.Models.Abstracts;
using WebSocket = yawaflua.WebSockets.Core.WebSocket;
using yawaflua.WebSockets.Models.Interfaces;
namespace Examples;
@@ -9,7 +9,7 @@ public class ChatController : WebSocketController
{
public override async Task OnMessageAsync(
WebSocket webSocket,
IWebSocket webSocket,
HttpContext httpContext)
{
await WebSocketManager.Broadcast(k => k.Path == "/chat", $"{webSocket.Client.Id}: {webSocket.Message}");

View File

@@ -1,8 +1,6 @@
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using yawaflua.WebSockets.Attributes;
using yawaflua.WebSockets.Core;
using yawaflua.WebSockets.Attributes;
using yawaflua.WebSockets.Models.Abstracts;
using yawaflua.WebSockets.Models.Interfaces;
namespace Examples;
@@ -11,7 +9,7 @@ public class TestWebSocketServer : WebSocketController
{
[WebSocket("/sub-test")]
public override async Task OnMessageAsync(WebSocket webSocket, HttpContext httpContext)
public override async Task OnMessageAsync(IWebSocket webSocket, HttpContext httpContext)
{
await webSocket.SendAsync("Test! Now on it endpoint: " + WebSocketManager.GetAllClients().Count(k => k.Path == webSocket.Client.Path));
}

View File

@@ -19,7 +19,7 @@ public class ChatController : WebSocketController
{
[WebSocket("/chat")]
public override async Task OnMessageAsync(
WebSocket webSocket,
IWebSocket webSocket,
HttpContext httpContext)
{
await webSocket.SendAsync("Message!");
@@ -58,7 +58,7 @@ public class NotificationsController : WebSocketController
{
[WebSocket("/notifications/{userId}")]
public override async Task OnMessageAsync(
WebSocket webSocket,
IWebSocket webSocket,
HttpContext httpContext)
{
var userId = httpContext.Request.RouteValues["userId"];
@@ -73,13 +73,13 @@ public class NotificationsController : WebSocketController
public class GameController : WebSocketController
{
[WebSocket("join/{roomId}")]
public async Task JoinRoom(WebSocket webSocket, HttpContext context)
public async Task JoinRoom(IWebSocket webSocket, HttpContext context)
{
// Handle room joining
}
[WebSocket("leave/{roomId}")]
public async Task LeaveRoom(WebSocket webSocket, HttpContext context)
public async Task LeaveRoom(IWebSocket webSocket, HttpContext context)
{
// Handle room leaving
}

View File

@@ -11,6 +11,7 @@ using Moq;
using Xunit;
using yawaflua.WebSockets.Attributes;
using yawaflua.WebSockets.Models.Abstracts;
using yawaflua.WebSockets.Models.Interfaces;
using Assert = Xunit.Assert;
using WebSocket = yawaflua.WebSockets.Core.WebSocket;
using WebSocketManager = Microsoft.AspNetCore.Http.WebSocketManager;
@@ -35,10 +36,10 @@ public class WebSocketRouterTests
public class TestHandler : WebSocketController
{
[yawaflua.WebSockets.Attributes.WebSocket("/static")]
public static Task StaticHandler(WebSocket ws, HttpContext context) => Task.CompletedTask;
public static Task StaticHandler(IWebSocket ws, HttpContext context) => Task.CompletedTask;
[yawaflua.WebSockets.Attributes.WebSocket("/instance")]
public Task InstanceHandler(WebSocket ws, HttpContext context) => Task.CompletedTask;
public Task InstanceHandler(IWebSocket ws, HttpContext context) => Task.CompletedTask;
}
[Fact]

View File

@@ -4,7 +4,7 @@ using yawaflua.WebSockets.Models.Interfaces;
namespace yawaflua.WebSockets.Core;
public class WebSocket : IDisposable
internal class WebSocket : IWebSocket
{
private readonly System.Net.WebSockets.WebSocket _webSocket;
private readonly WebSocketReceiveResult? _webSocketReceiveResult;
@@ -16,7 +16,7 @@ public class WebSocket : IDisposable
public string? CloseStatusDescription => _webSocket.CloseStatusDescription;
public string? Message => _message;
public WebSocketMessageType? MessageType => _webSocketReceiveResult?.MessageType;
public IWebSocketClient Client;
public IWebSocketClient Client { get; }
internal WebSocket(System.Net.WebSockets.WebSocket webSocket, WebSocketReceiveResult? webSocketReceiveResult, string? message, IWebSocketClient client)
{
_webSocket = webSocket;

View File

@@ -7,9 +7,18 @@ namespace yawaflua.WebSockets.Models.Abstracts;
public abstract class WebSocketController : IWebSocketController
{
/// <summary>
/// WebsocketManager provides work with all clients
/// </summary>
public IWebSocketManager WebSocketManager => new WebSocketManager();
public virtual Task OnMessageAsync(WebSocket webSocket, HttpContext httpContext)
/// <summary>
/// Example of function OnMessage
/// </summary>
/// <param name="webSocket">WebSocket with provided data about user e.t.c.</param>
/// <param name="httpContext">Http context of request</param>
/// <returns></returns>
public virtual Task OnMessageAsync(IWebSocket webSocket, HttpContext httpContext)
{
return Task.CompletedTask;
}

View File

@@ -0,0 +1,24 @@
using System.Net.WebSockets;
namespace yawaflua.WebSockets.Models.Interfaces;
public interface IWebSocket : IDisposable
{
WebSocketState State { get; }
WebSocketCloseStatus? CloseStatus { get; }
string? SubProtocol { get; }
string? CloseStatusDescription { get; }
string? Message { get; }
WebSocketMessageType? MessageType { get; }
IWebSocketClient Client { get; }
Task SendAsync(string message,
WebSocketMessageType messageType = WebSocketMessageType.Text,
CancellationToken cancellationToken = default);
Task CloseAsync(WebSocketCloseStatus closeStatus = WebSocketCloseStatus.NormalClosure,
string? reason = null,
CancellationToken cancellationToken = default);
void Abort();
}

View File

@@ -5,11 +5,33 @@ namespace yawaflua.WebSockets.Models.Interfaces;
public interface IWebSocketClient
{
/// <summary>
/// ID of user
/// </summary>
public Guid Id { get; }
/// <summary>
/// Path, that user connects
/// </summary>
public string Path { get; }
/// <summary>
/// Connection info
/// </summary>
public ConnectionInfo? ConnectionInfo { get; }
/// <summary>
/// You can provides Items, like in auth middleware or any
/// </summary>
public IDictionary<object, object>? Items { get; set; }
/// <summary>
/// HttpRequest data
/// </summary>
public HttpRequest? HttpRequest { get; }
/// <summary>
/// You should`nt use it, but, its full work with user
/// </summary>
internal WebSocket webSocket { get; }
/// <summary>
/// Kick client
/// </summary>
/// <returns>null</returns>
public Task Abort();
}

View File

@@ -5,5 +5,11 @@ namespace yawaflua.WebSockets.Models.Interfaces;
internal interface IWebSocketController
{
Task OnMessageAsync(WebSocket webSocket, HttpContext httpContext);
/// <summary>
/// Example of working with IWebSocketController
/// </summary>
/// <param name="webSocket"></param>
/// <param name="httpContext"></param>
/// <returns></returns>
Task OnMessageAsync(IWebSocket webSocket, HttpContext httpContext);
}

View File

@@ -5,7 +5,28 @@ namespace yawaflua.WebSockets.Models.Interfaces;
public interface IWebSocketManager
{
/// <summary>
/// Broadcast message to all users
/// </summary>
/// <param name="selector">selector of users</param>
/// <param name="message">message, broadcasted to all users</param>
/// <param name="messageType">type of message</param>
/// <param name="cts">cancellation token</param>
/// <returns></returns>
public Task Broadcast(Func<IWebSocketClient, bool> selector,string message, WebSocketMessageType messageType = WebSocketMessageType.Text, CancellationToken cts = default);
/// <summary>
/// Provides list of clients connected to host
/// </summary>
/// <returns></returns>
public List<IWebSocketClient> GetAllClients();
/// <summary>
/// Send to specific user data
/// Analog of <c>Broadcast(k => k.Id == ID, message)</c>
/// </summary>
/// <param name="id">Id of user</param>
/// <param name="message">message to user</param>
/// <param name="messageType">type of message</param>
/// <param name="cts">cancellation token</param>
/// <returns></returns>
public Task SendToUser(Guid id, string message, WebSocketMessageType messageType, CancellationToken cts);
}

View File

@@ -4,15 +4,18 @@
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>1.0.0</Version>
<Version>0.0.9</Version>
<Title>yawaflua.WebSockets</Title>
<Description>New AspNet controllers looks like websocket manager </Description>
<Copyright>Dmitrii Shimanskii</Copyright>
<PackageProjectUrl>https://github.com/yawaflua/WebSockets</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/yawaflua/WebSockets/LICENCE</PackageLicenseUrl>
<RepositoryUrl>https://github.com/yawaflua/WebSockets</RepositoryUrl>
<Read>https://github.com/yawaflua/WebSockets</Read>
<PackageTags>websocket</PackageTags>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
<ItemGroup>