Updated Service to use events

This commit is contained in:
martin 2023-05-29 00:24:03 +02:00
parent 3d95ff71d6
commit 69ec14c04c
3 changed files with 22 additions and 59 deletions

View File

@ -8,6 +8,7 @@ public abstract class GenericController : ControllerBase
{
protected readonly ILogger<GenericController> Logger;
private readonly IWebSocketService _wsService;
private WebSocket? _webSocket;
private const int BufferSize = 1024 * 4;
protected GenericController(ILogger<GenericController> logger, IWebSocketService wsService)
@ -23,8 +24,9 @@ public abstract class GenericController : ControllerBase
{
using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
Logger.Log(LogLevel.Information, "WebSocket connection established to {}", HttpContext.Connection.Id);
_wsService.Add(webSocket);
await Echo(webSocket);
_webSocket = webSocket;
_wsService.Connections += WsServiceOnFire;
await Echo();
}
else
{
@ -32,31 +34,39 @@ public abstract class GenericController : ControllerBase
}
}
protected virtual async Task Echo(WebSocket webSocket)
private async Task WsServiceOnFire(ArraySegment<byte> segment)
{
if (_webSocket == null) return;
await _wsService.Send(_webSocket, segment);
}
protected virtual async Task Echo()
{
if (_webSocket == null) return;
try
{
WebSocketReceiveResult? result;
do
{
var buffer = new byte[BufferSize];
result = await _wsService.Receive(webSocket, buffer);
result = await _wsService.Receive(_webSocket, buffer);
if (result.CloseStatus.HasValue) break;
var segment = Run(result, buffer);
await _wsService.SendToAll(segment);
_wsService.SendToAll(segment);
} while (true);
await _wsService.Close(webSocket, result.CloseStatus.Value, result.CloseStatusDescription ?? "No reason");
await _wsService.Close(_webSocket, result.CloseStatus.Value, result.CloseStatusDescription ?? "No reason");
}
catch (WebSocketException e)
{
Logger.Log(LogLevel.Error, "{}", e.Message);
}
_wsService.Remove(webSocket);
_wsService.Connections -= WsServiceOnFire;
}
protected abstract ArraySegment<byte> Run(WebSocketReceiveResult result, byte[] data);

View File

@ -4,14 +4,9 @@ namespace pacMan.Interfaces;
public interface IWebSocketService
{
void Add(WebSocket webSocket);
bool Remove(WebSocket webSocket);
Task Send(WebSocket webSocket, string message, int length);
Task Send(WebSocket webSocket, byte[] message, int length);
event Func<ArraySegment<byte>, Task>? Connections;
Task Send(WebSocket webSocket, ArraySegment<byte> segment);
Task SendToAll(string message, int length);
Task SendToAll(byte[] message, int length);
Task SendToAll(ArraySegment<byte> segment);
void SendToAll(ArraySegment<byte> segment);
Task<WebSocketReceiveResult> Receive(WebSocket webSocket, byte[] buffer);
Task Close(WebSocket webSocket, WebSocketCloseStatus closeStatus, string closeStatusDescription);
int CountConnected();

View File

@ -1,5 +1,4 @@
using System.Net.WebSockets;
using System.Text;
using pacMan.Interfaces;
using pacMan.Utils;
@ -8,7 +7,7 @@ namespace pacMan.Services;
public class WebSocketService : IWebSocketService
{
private readonly ILogger<WebSocketService> _logger;
private readonly SynchronizedCollection<WebSocket> _webSockets = new(); // TODO separate connections into groups
public event Func<ArraySegment<byte>, Task>? Connections; // TODO separate connections into groups (1 event per game)
public WebSocketService(ILogger<WebSocketService> logger)
{
@ -16,31 +15,6 @@ public class WebSocketService : IWebSocketService
logger.Log(LogLevel.Debug, "WebSocket Service created");
}
public void Add(WebSocket webSocket)
{
_webSockets.Add(webSocket);
_logger.Log(LogLevel.Debug, "WebSocket added to list");
}
public bool Remove(WebSocket webSocket)
{
var taken = _webSockets.Remove(webSocket);
_logger.Log(LogLevel.Debug, "WebSocket removed from list");
return taken;
}
public async Task Send(WebSocket webSocket, string message, int length)
{
var bytes = Encoding.UTF8.GetBytes(message);
await Send(webSocket, bytes, length);
}
public async Task Send(WebSocket webSocket, byte[] message, int length)
{
var msgSegment = new ArraySegment<byte>(message, 0, length);
await Send(webSocket, msgSegment);
}
public async Task Send(WebSocket webSocket, ArraySegment<byte> segment)
{
await webSocket.SendAsync(
@ -52,23 +26,7 @@ public class WebSocketService : IWebSocketService
_logger.Log(LogLevel.Trace, "Message sent to WebSocket");
}
public async Task SendToAll(string message, int length)
{
var serverMsg = Encoding.UTF8.GetBytes(message);
await SendToAll(serverMsg, length);
}
public async Task SendToAll(byte[] message, int length)
{
foreach (var ws in _webSockets) await Send(ws, message, length);
_logger.Log(LogLevel.Debug, "Message sent to all WebSockets");
}
public async Task SendToAll(ArraySegment<byte> segment)
{
foreach (var ws in _webSockets) await Send(ws, segment);
}
public void SendToAll(ArraySegment<byte> segment) => Connections?.Invoke(segment);
public async Task<WebSocketReceiveResult> Receive(WebSocket webSocket, byte[] buffer)
{
@ -89,5 +47,5 @@ public class WebSocketService : IWebSocketService
_logger.Log(LogLevel.Information, "WebSocket connection closed");
}
public int CountConnected() => _webSockets.Count;
public int CountConnected() => Connections?.GetInvocationList().Length ?? 0;
}