74 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			74 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System.Net.WebSockets;
 | |
| using Microsoft.Extensions.Hosting;
 | |
| using Microsoft.Extensions.Logging;
 | |
| using TanksServer.Helpers;
 | |
| using TanksServer.Services;
 | |
| 
 | |
| namespace TanksServer;
 | |
| 
 | |
| internal sealed class ClientScreenServer(
 | |
|     ILogger<ClientScreenServer> logger,
 | |
|     ILoggerFactory loggerFactory,
 | |
|     MapDrawer drawer
 | |
| ) : IHostedLifecycleService, ITickStep
 | |
| {
 | |
|     private readonly List<ClientScreenServerConnection> _connections = new();
 | |
| 
 | |
|     public Task HandleClient(WebSocket socket)
 | |
|     {
 | |
|         logger.LogDebug("HandleClient");
 | |
|         var connection =
 | |
|             new ClientScreenServerConnection(socket, loggerFactory.CreateLogger<ClientScreenServerConnection>(), this);
 | |
|         _connections.Add(connection);
 | |
|         return connection.Done;
 | |
|     }
 | |
| 
 | |
|     public Task StoppingAsync(CancellationToken cancellationToken)
 | |
|     {
 | |
|         logger.LogInformation("closing connections");
 | |
|         return Task.WhenAll(_connections.Select(c => c.CloseAsync()));
 | |
|     }
 | |
| 
 | |
|     public Task TickAsync()
 | |
|     {
 | |
|         logger.LogTrace("Sending buffer to {} clients", _connections.Count);
 | |
|         return Task.WhenAll(_connections.Select(c => c.SendAsync(drawer.LastFrame)));
 | |
|     }
 | |
| 
 | |
|     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;
 | |
|     
 | |
|     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;
 | |
| 
 | |
|         public Task SendAsync(DisplayPixelBuffer buf)
 | |
|         {
 | |
|             if (!_wantsNewFrame)
 | |
|                 return Task.CompletedTask;
 | |
|             _wantsNewFrame = false;
 | |
|             return TrySendAsync(buf.Data);
 | |
|         }
 | |
| 
 | |
|         protected override Task ReceiveAsync(ArraySegment<byte> buffer)
 | |
|         {
 | |
|             _wantsNewFrame = true;
 | |
|             return Task.CompletedTask;
 | |
|         }
 | |
| 
 | |
|         protected override Task ClosingAsync()
 | |
|         {
 | |
|             server.Remove(this);
 | |
|             return Task.CompletedTask;
 | |
|         }
 | |
|     }
 | |
| }
 | 
