using System.Net.WebSockets; using System.Text; using MauMau_Server.Websockets; using Microsoft.AspNetCore.Mvc; namespace MauMau_Server.Controllers; [ApiController] [Route("[controller]")] public class WebSocketsController : ControllerBase { private readonly ILogger _logger; private readonly IWebsocketManager _websocketManager; private string _id = string.Empty; public WebSocketsController(ILogger logger, IWebsocketManager websocketManager) { _logger = logger; _websocketManager = websocketManager; } [HttpGet("/ws")] public async Task Get() { if (HttpContext.WebSockets.IsWebSocketRequest) { using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); _id = _websocketManager.AddConnection(webSocket); _logger.Log(LogLevel.Information, $"WebSocket connection {_id} established"); await Echo(webSocket); } else { HttpContext.Response.StatusCode = 400; } } private async Task Echo(WebSocket webSocket) { var buffer = EmptyBuffer(); var result = await ReceiveAsync(webSocket, buffer); while (!result.CloseStatus.HasValue) { var message = Encoding.UTF8.GetString(buffer); BroadcastAsync(message); buffer = EmptyBuffer(); result = await ReceiveAsync(webSocket, buffer); } await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); _websocketManager.RemoveConnection(_id); _logger.Log(LogLevel.Information, $"WebSocket connection {_id} closed"); } private async Task ReceiveAsync(WebSocket webSocket, byte[] buffer) { var arraySegment = new ArraySegment(buffer); var result = await webSocket.ReceiveAsync(arraySegment, CancellationToken.None); _logger.Log(LogLevel.Information, $"Message received from Client {_id}"); return result; } private void BroadcastAsync(string message) { var bytes = Encoding.Default.GetBytes($"{_id}: {message}"); var arraySegment = new ArraySegment(bytes); foreach (var (id, socket) in _websocketManager.GetAllConnections()) { socket.SendAsync(arraySegment, WebSocketMessageType.Text, true, CancellationToken.None); _logger.Log(LogLevel.Information, $"Message from Client {_id} sent to Client {id}"); } } private static byte[] EmptyBuffer() { return new byte[4096]; } }