Updated Service to use events
This commit is contained in:
parent
3d95ff71d6
commit
69ec14c04c
@ -8,6 +8,7 @@ public abstract class GenericController : ControllerBase
|
|||||||
{
|
{
|
||||||
protected readonly ILogger<GenericController> Logger;
|
protected readonly ILogger<GenericController> Logger;
|
||||||
private readonly IWebSocketService _wsService;
|
private readonly IWebSocketService _wsService;
|
||||||
|
private WebSocket? _webSocket;
|
||||||
private const int BufferSize = 1024 * 4;
|
private const int BufferSize = 1024 * 4;
|
||||||
|
|
||||||
protected GenericController(ILogger<GenericController> logger, IWebSocketService wsService)
|
protected GenericController(ILogger<GenericController> logger, IWebSocketService wsService)
|
||||||
@ -23,8 +24,9 @@ public abstract class GenericController : ControllerBase
|
|||||||
{
|
{
|
||||||
using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
|
using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
|
||||||
Logger.Log(LogLevel.Information, "WebSocket connection established to {}", HttpContext.Connection.Id);
|
Logger.Log(LogLevel.Information, "WebSocket connection established to {}", HttpContext.Connection.Id);
|
||||||
_wsService.Add(webSocket);
|
_webSocket = webSocket;
|
||||||
await Echo(webSocket);
|
_wsService.Connections += WsServiceOnFire;
|
||||||
|
await Echo();
|
||||||
}
|
}
|
||||||
else
|
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
|
try
|
||||||
{
|
{
|
||||||
WebSocketReceiveResult? result;
|
WebSocketReceiveResult? result;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
var buffer = new byte[BufferSize];
|
var buffer = new byte[BufferSize];
|
||||||
result = await _wsService.Receive(webSocket, buffer);
|
result = await _wsService.Receive(_webSocket, buffer);
|
||||||
|
|
||||||
if (result.CloseStatus.HasValue) break;
|
if (result.CloseStatus.HasValue) break;
|
||||||
|
|
||||||
var segment = Run(result, buffer);
|
var segment = Run(result, buffer);
|
||||||
|
|
||||||
await _wsService.SendToAll(segment);
|
_wsService.SendToAll(segment);
|
||||||
} while (true);
|
} 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)
|
catch (WebSocketException e)
|
||||||
{
|
{
|
||||||
Logger.Log(LogLevel.Error, "{}", e.Message);
|
Logger.Log(LogLevel.Error, "{}", e.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
_wsService.Remove(webSocket);
|
_wsService.Connections -= WsServiceOnFire;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract ArraySegment<byte> Run(WebSocketReceiveResult result, byte[] data);
|
protected abstract ArraySegment<byte> Run(WebSocketReceiveResult result, byte[] data);
|
||||||
|
@ -4,14 +4,9 @@ namespace pacMan.Interfaces;
|
|||||||
|
|
||||||
public interface IWebSocketService
|
public interface IWebSocketService
|
||||||
{
|
{
|
||||||
void Add(WebSocket webSocket);
|
event Func<ArraySegment<byte>, Task>? Connections;
|
||||||
bool Remove(WebSocket webSocket);
|
|
||||||
Task Send(WebSocket webSocket, string message, int length);
|
|
||||||
Task Send(WebSocket webSocket, byte[] message, int length);
|
|
||||||
Task Send(WebSocket webSocket, ArraySegment<byte> segment);
|
Task Send(WebSocket webSocket, ArraySegment<byte> segment);
|
||||||
Task SendToAll(string message, int length);
|
void SendToAll(ArraySegment<byte> segment);
|
||||||
Task SendToAll(byte[] message, int length);
|
|
||||||
Task SendToAll(ArraySegment<byte> segment);
|
|
||||||
Task<WebSocketReceiveResult> Receive(WebSocket webSocket, byte[] buffer);
|
Task<WebSocketReceiveResult> Receive(WebSocket webSocket, byte[] buffer);
|
||||||
Task Close(WebSocket webSocket, WebSocketCloseStatus closeStatus, string closeStatusDescription);
|
Task Close(WebSocket webSocket, WebSocketCloseStatus closeStatus, string closeStatusDescription);
|
||||||
int CountConnected();
|
int CountConnected();
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Text;
|
|
||||||
using pacMan.Interfaces;
|
using pacMan.Interfaces;
|
||||||
using pacMan.Utils;
|
using pacMan.Utils;
|
||||||
|
|
||||||
@ -8,7 +7,7 @@ namespace pacMan.Services;
|
|||||||
public class WebSocketService : IWebSocketService
|
public class WebSocketService : IWebSocketService
|
||||||
{
|
{
|
||||||
private readonly ILogger<WebSocketService> _logger;
|
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)
|
public WebSocketService(ILogger<WebSocketService> logger)
|
||||||
{
|
{
|
||||||
@ -16,31 +15,6 @@ public class WebSocketService : IWebSocketService
|
|||||||
logger.Log(LogLevel.Debug, "WebSocket Service created");
|
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)
|
public async Task Send(WebSocket webSocket, ArraySegment<byte> segment)
|
||||||
{
|
{
|
||||||
await webSocket.SendAsync(
|
await webSocket.SendAsync(
|
||||||
@ -52,23 +26,7 @@ public class WebSocketService : IWebSocketService
|
|||||||
_logger.Log(LogLevel.Trace, "Message sent to WebSocket");
|
_logger.Log(LogLevel.Trace, "Message sent to WebSocket");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendToAll(string message, int length)
|
public void SendToAll(ArraySegment<byte> segment) => Connections?.Invoke(segment);
|
||||||
{
|
|
||||||
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 async Task<WebSocketReceiveResult> Receive(WebSocket webSocket, byte[] buffer)
|
public async Task<WebSocketReceiveResult> Receive(WebSocket webSocket, byte[] buffer)
|
||||||
{
|
{
|
||||||
@ -89,5 +47,5 @@ public class WebSocketService : IWebSocketService
|
|||||||
_logger.Log(LogLevel.Information, "WebSocket connection closed");
|
_logger.Log(LogLevel.Information, "WebSocket connection closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CountConnected() => _webSockets.Count;
|
public int CountConnected() => Connections?.GetInvocationList().Length ?? 0;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user