more configuration, limit rate of sent frames

This commit is contained in:
Vinzenz Schroeter 2024-04-16 21:34:54 +02:00
parent 786c974a23
commit 3f4a301993
10 changed files with 104 additions and 45 deletions

View file

@ -8,10 +8,12 @@ namespace TanksServer.Interactivity;
internal sealed class ClientScreenServer(
ILogger<ClientScreenServer> logger,
ILoggerFactory loggerFactory
ILoggerFactory loggerFactory,
IOptions<HostConfiguration> hostConfig
) : IHostedLifecycleService, IFrameConsumer
{
private readonly ConcurrentDictionary<ClientScreenServerConnection, byte> _connections = new();
private readonly TimeSpan _minFrameTime = TimeSpan.FromMilliseconds(hostConfig.Value.ClientDisplayMinFrameTimeMs);
private bool _closing;
public Task StoppingAsync(CancellationToken cancellationToken)
@ -34,6 +36,7 @@ internal sealed class ClientScreenServer(
socket,
loggerFactory.CreateLogger<ClientScreenServerConnection>(),
this,
_minFrameTime,
playerGuid);
var added = _connections.TryAdd(connection, 0);
Debug.Assert(added);

View file

@ -11,18 +11,23 @@ internal sealed class ClientScreenServerConnection : IDisposable
private readonly ILogger<ClientScreenServerConnection> _logger;
private readonly ClientScreenServer _server;
private readonly SemaphoreSlim _wantedFrames = new(1);
private readonly Guid? _playerGuid = null;
private readonly PlayerScreenData? _playerScreenData = null;
private readonly Guid? _playerGuid;
private readonly PlayerScreenData? _playerScreenData;
private readonly TimeSpan _minFrameTime;
private DateTime _nextFrameAfter = DateTime.Now;
public ClientScreenServerConnection(
WebSocket webSocket,
ILogger<ClientScreenServerConnection> logger,
ClientScreenServer server,
TimeSpan minFrameTime,
Guid? playerGuid = null
)
{
_server = server;
_logger = logger;
_minFrameTime = minFrameTime;
_playerGuid = playerGuid;
if (playerGuid.HasValue)
@ -42,12 +47,17 @@ internal sealed class ClientScreenServerConnection : IDisposable
public async Task SendAsync(PixelGrid pixels, GamePixelGrid gamePixelGrid)
{
if (_nextFrameAfter > DateTime.Now)
return;
if (!await _wantedFrames.WaitAsync(TimeSpan.Zero))
{
_logger.LogTrace("client does not want a frame yet");
return;
}
_nextFrameAfter = DateTime.Today + _minFrameTime;
if (_playerScreenData != null)
RefreshPlayerSpecificData(gamePixelGrid);

View file

@ -16,17 +16,22 @@ internal sealed class SendToServicePointDisplay : IFrameConsumer
private readonly ILogger<SendToServicePointDisplay> _logger;
private readonly PlayerServer _players;
private readonly Cp437Grid _scoresBuffer;
private DateTime _nextFailLog = DateTime.Now;
private readonly TimeSpan _minFrameTime;
private DateTime _nextFailLogAfter = DateTime.Now;
private DateTime _nextFrameAfter = DateTime.Now;
public SendToServicePointDisplay(
PlayerServer players,
ILogger<SendToServicePointDisplay> logger,
IDisplayConnection displayConnection
IDisplayConnection displayConnection,
IOptions<HostConfiguration> hostOptions
)
{
_players = players;
_logger = logger;
_displayConnection = displayConnection;
_minFrameTime = TimeSpan.FromMilliseconds(hostOptions.Value.ServicePointDisplayMinFrameTimeMs);
var localIp = _displayConnection.GetLocalIPv4().Split('.');
Debug.Assert(localIp.Length == 4);
@ -42,7 +47,12 @@ internal sealed class SendToServicePointDisplay : IFrameConsumer
public async Task OnFrameDoneAsync(GamePixelGrid gamePixelGrid, PixelGrid observerPixels)
{
if (DateTime.Now < _nextFrameAfter)
return;
_nextFrameAfter = DateTime.Now + _minFrameTime;
RefreshScores();
try
{
await _displayConnection.SendBitmapLinearWindowAsync(0, 0, observerPixels);
@ -50,10 +60,10 @@ internal sealed class SendToServicePointDisplay : IFrameConsumer
}
catch (SocketException ex)
{
if (DateTime.Now > _nextFailLog)
if (DateTime.Now > _nextFailLogAfter)
{
_logger.LogWarning("could not send data to service point display: {}", ex.Message);
_nextFailLog = DateTime.Now + TimeSpan.FromSeconds(5);
_nextFailLogAfter = DateTime.Now + TimeSpan.FromSeconds(5);
}
}
}