servicepoint-tanks/TanksServer/ClientScreenServer.cs

73 lines
2.4 KiB
C#
Raw Normal View History

2024-04-06 16:38:26 +02:00
using System.Net.WebSockets;
2024-04-06 20:32:54 +02:00
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
2024-04-06 16:38:26 +02:00
namespace TanksServer;
2024-04-06 20:32:54 +02:00
internal sealed class ClientScreenServer(
ILogger<ClientScreenServer> logger,
2024-04-06 21:15:26 +02:00
ILoggerFactory loggerFactory,
MapDrawer drawer
) : IHostedLifecycleService, ITickStep
2024-04-06 16:38:26 +02:00
{
private readonly List<ClientScreenServerConnection> _connections = new();
2024-04-06 20:32:54 +02:00
public Task HandleClient(WebSocket socket)
2024-04-06 16:38:26 +02:00
{
2024-04-06 20:32:54 +02:00
logger.LogDebug("HandleClient");
var connection =
2024-04-06 21:15:26 +02:00
new ClientScreenServerConnection(socket, loggerFactory.CreateLogger<ClientScreenServerConnection>(), this);
2024-04-06 16:38:26 +02:00
_connections.Add(connection);
2024-04-06 20:32:54 +02:00
return connection.Done;
2024-04-06 16:38:26 +02:00
}
2024-04-06 20:32:54 +02:00
public Task StoppingAsync(CancellationToken cancellationToken)
2024-04-06 16:38:26 +02:00
{
2024-04-06 20:32:54 +02:00
logger.LogInformation("closing connections");
return Task.WhenAll(_connections.Select(c => c.CloseAsync()));
2024-04-06 16:38:26 +02:00
}
2024-04-06 21:15:26 +02:00
public Task TickAsync()
{
logger.LogTrace("Sending buffer to {} clients", _connections.Count);
return Task.WhenAll(_connections.Select(c => c.SendAsync(drawer.LastFrame)));
}
2024-04-06 20:32:54 +02:00
public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public Task StartedAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public Task StartingAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public Task StoppedAsync(CancellationToken cancellationToken) => Task.CompletedTask;
2024-04-06 21:15:26 +02:00
private void Remove(ClientScreenServerConnection connection) => _connections.Remove(connection);
private sealed class ClientScreenServerConnection(
WebSocket webSocket,
ILogger<ClientScreenServerConnection> logger,
ClientScreenServer server
) : EasyWebSocket(webSocket, logger, ArraySegment<byte>.Empty)
{
private bool _wantsNewFrame = true;
2024-04-06 16:38:26 +02:00
2024-04-06 21:15:26 +02:00
public Task SendAsync(DisplayPixelBuffer buf)
{
if (!_wantsNewFrame)
return Task.CompletedTask;
_wantsNewFrame = false;
return TrySendAsync(buf.Data);
}
2024-04-06 16:38:26 +02:00
2024-04-06 21:15:26 +02:00
protected override Task ReceiveAsync(ArraySegment<byte> buffer)
{
_wantsNewFrame = true;
2024-04-06 16:38:26 +02:00
return Task.CompletedTask;
2024-04-06 21:15:26 +02:00
}
2024-04-06 20:32:54 +02:00
2024-04-06 21:15:26 +02:00
protected override Task ClosingAsync()
{
server.Remove(this);
return Task.CompletedTask;
}
2024-04-06 16:38:26 +02:00
}
}