mirror of
https://github.com/yawaflua/WebSockets.git
synced 2025-12-08 19:39:30 +02:00
adds comments, OOP incapsulation and publish package to nuget
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
using yawaflua.WebSockets.Attributes;
|
using yawaflua.WebSockets.Attributes;
|
||||||
using yawaflua.WebSockets.Models.Abstracts;
|
using yawaflua.WebSockets.Models.Abstracts;
|
||||||
using WebSocket = yawaflua.WebSockets.Core.WebSocket;
|
using yawaflua.WebSockets.Models.Interfaces;
|
||||||
|
|
||||||
namespace Examples;
|
namespace Examples;
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ public class ChatController : WebSocketController
|
|||||||
{
|
{
|
||||||
|
|
||||||
public override async Task OnMessageAsync(
|
public override async Task OnMessageAsync(
|
||||||
WebSocket webSocket,
|
IWebSocket webSocket,
|
||||||
HttpContext httpContext)
|
HttpContext httpContext)
|
||||||
{
|
{
|
||||||
await WebSocketManager.Broadcast(k => k.Path == "/chat", $"{webSocket.Client.Id}: {webSocket.Message}");
|
await WebSocketManager.Broadcast(k => k.Path == "/chat", $"{webSocket.Client.Id}: {webSocket.Message}");
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using System.Text.Json;
|
using yawaflua.WebSockets.Attributes;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using yawaflua.WebSockets.Attributes;
|
|
||||||
using yawaflua.WebSockets.Core;
|
|
||||||
using yawaflua.WebSockets.Models.Abstracts;
|
using yawaflua.WebSockets.Models.Abstracts;
|
||||||
|
using yawaflua.WebSockets.Models.Interfaces;
|
||||||
|
|
||||||
namespace Examples;
|
namespace Examples;
|
||||||
|
|
||||||
@@ -11,7 +9,7 @@ public class TestWebSocketServer : WebSocketController
|
|||||||
{
|
{
|
||||||
|
|
||||||
[WebSocket("/sub-test")]
|
[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));
|
await webSocket.SendAsync("Test! Now on it endpoint: " + WebSocketManager.GetAllClients().Count(k => k.Path == webSocket.Client.Path));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class ChatController : WebSocketController
|
|||||||
{
|
{
|
||||||
[WebSocket("/chat")]
|
[WebSocket("/chat")]
|
||||||
public override async Task OnMessageAsync(
|
public override async Task OnMessageAsync(
|
||||||
WebSocket webSocket,
|
IWebSocket webSocket,
|
||||||
HttpContext httpContext)
|
HttpContext httpContext)
|
||||||
{
|
{
|
||||||
await webSocket.SendAsync("Message!");
|
await webSocket.SendAsync("Message!");
|
||||||
@@ -58,7 +58,7 @@ public class NotificationsController : WebSocketController
|
|||||||
{
|
{
|
||||||
[WebSocket("/notifications/{userId}")]
|
[WebSocket("/notifications/{userId}")]
|
||||||
public override async Task OnMessageAsync(
|
public override async Task OnMessageAsync(
|
||||||
WebSocket webSocket,
|
IWebSocket webSocket,
|
||||||
HttpContext httpContext)
|
HttpContext httpContext)
|
||||||
{
|
{
|
||||||
var userId = httpContext.Request.RouteValues["userId"];
|
var userId = httpContext.Request.RouteValues["userId"];
|
||||||
@@ -73,13 +73,13 @@ public class NotificationsController : WebSocketController
|
|||||||
public class GameController : WebSocketController
|
public class GameController : WebSocketController
|
||||||
{
|
{
|
||||||
[WebSocket("join/{roomId}")]
|
[WebSocket("join/{roomId}")]
|
||||||
public async Task JoinRoom(WebSocket webSocket, HttpContext context)
|
public async Task JoinRoom(IWebSocket webSocket, HttpContext context)
|
||||||
{
|
{
|
||||||
// Handle room joining
|
// Handle room joining
|
||||||
}
|
}
|
||||||
|
|
||||||
[WebSocket("leave/{roomId}")]
|
[WebSocket("leave/{roomId}")]
|
||||||
public async Task LeaveRoom(WebSocket webSocket, HttpContext context)
|
public async Task LeaveRoom(IWebSocket webSocket, HttpContext context)
|
||||||
{
|
{
|
||||||
// Handle room leaving
|
// Handle room leaving
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using Moq;
|
|||||||
using Xunit;
|
using Xunit;
|
||||||
using yawaflua.WebSockets.Attributes;
|
using yawaflua.WebSockets.Attributes;
|
||||||
using yawaflua.WebSockets.Models.Abstracts;
|
using yawaflua.WebSockets.Models.Abstracts;
|
||||||
|
using yawaflua.WebSockets.Models.Interfaces;
|
||||||
using Assert = Xunit.Assert;
|
using Assert = Xunit.Assert;
|
||||||
using WebSocket = yawaflua.WebSockets.Core.WebSocket;
|
using WebSocket = yawaflua.WebSockets.Core.WebSocket;
|
||||||
using WebSocketManager = Microsoft.AspNetCore.Http.WebSocketManager;
|
using WebSocketManager = Microsoft.AspNetCore.Http.WebSocketManager;
|
||||||
@@ -35,10 +36,10 @@ public class WebSocketRouterTests
|
|||||||
public class TestHandler : WebSocketController
|
public class TestHandler : WebSocketController
|
||||||
{
|
{
|
||||||
[yawaflua.WebSockets.Attributes.WebSocket("/static")]
|
[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")]
|
[yawaflua.WebSockets.Attributes.WebSocket("/instance")]
|
||||||
public Task InstanceHandler(WebSocket ws, HttpContext context) => Task.CompletedTask;
|
public Task InstanceHandler(IWebSocket ws, HttpContext context) => Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using yawaflua.WebSockets.Models.Interfaces;
|
|||||||
|
|
||||||
namespace yawaflua.WebSockets.Core;
|
namespace yawaflua.WebSockets.Core;
|
||||||
|
|
||||||
public class WebSocket : IDisposable
|
internal class WebSocket : IWebSocket
|
||||||
{
|
{
|
||||||
private readonly System.Net.WebSockets.WebSocket _webSocket;
|
private readonly System.Net.WebSockets.WebSocket _webSocket;
|
||||||
private readonly WebSocketReceiveResult? _webSocketReceiveResult;
|
private readonly WebSocketReceiveResult? _webSocketReceiveResult;
|
||||||
@@ -16,7 +16,7 @@ public class WebSocket : IDisposable
|
|||||||
public string? CloseStatusDescription => _webSocket.CloseStatusDescription;
|
public string? CloseStatusDescription => _webSocket.CloseStatusDescription;
|
||||||
public string? Message => _message;
|
public string? Message => _message;
|
||||||
public WebSocketMessageType? MessageType => _webSocketReceiveResult?.MessageType;
|
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)
|
internal WebSocket(System.Net.WebSockets.WebSocket webSocket, WebSocketReceiveResult? webSocketReceiveResult, string? message, IWebSocketClient client)
|
||||||
{
|
{
|
||||||
_webSocket = webSocket;
|
_webSocket = webSocket;
|
||||||
|
|||||||
@@ -7,9 +7,18 @@ namespace yawaflua.WebSockets.Models.Abstracts;
|
|||||||
|
|
||||||
public abstract class WebSocketController : IWebSocketController
|
public abstract class WebSocketController : IWebSocketController
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// WebsocketManager provides work with all clients
|
||||||
|
/// </summary>
|
||||||
public IWebSocketManager WebSocketManager => new WebSocketManager();
|
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;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|||||||
24
yawaflua.WebSockets/Models/Interfaces/IWebSocket.cs
Normal file
24
yawaflua.WebSockets/Models/Interfaces/IWebSocket.cs
Normal 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();
|
||||||
|
}
|
||||||
@@ -5,11 +5,33 @@ namespace yawaflua.WebSockets.Models.Interfaces;
|
|||||||
|
|
||||||
public interface IWebSocketClient
|
public interface IWebSocketClient
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// ID of user
|
||||||
|
/// </summary>
|
||||||
public Guid Id { get; }
|
public Guid Id { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Path, that user connects
|
||||||
|
/// </summary>
|
||||||
public string Path { get; }
|
public string Path { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Connection info
|
||||||
|
/// </summary>
|
||||||
public ConnectionInfo? ConnectionInfo { get; }
|
public ConnectionInfo? ConnectionInfo { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// You can provides Items, like in auth middleware or any
|
||||||
|
/// </summary>
|
||||||
public IDictionary<object, object>? Items { get; set; }
|
public IDictionary<object, object>? Items { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// HttpRequest data
|
||||||
|
/// </summary>
|
||||||
public HttpRequest? HttpRequest { get; }
|
public HttpRequest? HttpRequest { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// You should`nt use it, but, its full work with user
|
||||||
|
/// </summary>
|
||||||
internal WebSocket webSocket { get; }
|
internal WebSocket webSocket { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Kick client
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>null</returns>
|
||||||
public Task Abort();
|
public Task Abort();
|
||||||
}
|
}
|
||||||
@@ -5,5 +5,11 @@ namespace yawaflua.WebSockets.Models.Interfaces;
|
|||||||
|
|
||||||
internal interface IWebSocketController
|
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);
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,28 @@ namespace yawaflua.WebSockets.Models.Interfaces;
|
|||||||
|
|
||||||
public interface IWebSocketManager
|
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);
|
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();
|
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);
|
public Task SendToUser(Guid id, string message, WebSocketMessageType messageType, CancellationToken cts);
|
||||||
}
|
}
|
||||||
@@ -4,15 +4,18 @@
|
|||||||
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
|
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Version>1.0.0</Version>
|
<Version>0.0.9</Version>
|
||||||
<Title>yawaflua.WebSockets</Title>
|
<Title>yawaflua.WebSockets</Title>
|
||||||
<Description>New AspNet controllers looks like websocket manager </Description>
|
<Description>New AspNet controllers looks like websocket manager </Description>
|
||||||
<Copyright>Dmitrii Shimanskii</Copyright>
|
<Copyright>Dmitrii Shimanskii</Copyright>
|
||||||
<PackageProjectUrl>https://github.com/yawaflua/WebSockets</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/yawaflua/WebSockets</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/yawaflua/WebSockets/LICENCE</PackageLicenseUrl>
|
|
||||||
<RepositoryUrl>https://github.com/yawaflua/WebSockets</RepositoryUrl>
|
<RepositoryUrl>https://github.com/yawaflua/WebSockets</RepositoryUrl>
|
||||||
|
<Read>https://github.com/yawaflua/WebSockets</Read>
|
||||||
<PackageTags>websocket</PackageTags>
|
<PackageTags>websocket</PackageTags>
|
||||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
||||||
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
|
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||||
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user