Meum/Meum.Server/ClientConnection.cs
2025-07-05 01:21:18 +03:00

93 lines
2.9 KiB
C#

using System.Net.Quic;
using DTLib.Logging;
using Meum.Core.Messages;
namespace Meum.Server;
public class ClientConnection : IAsyncDisposable
{
private readonly QuicConnection _quicConnection;
private QuicStreamWrapper _systemStream;
private ContextLogger _logger;
private CancellationTokenSource _connectionCts = new();
public int Id { get; }
public bool IsAuthorized { get; private set; }
private ClientConnection(int id, QuicConnection quicConnection, QuicStreamWrapper systemStream, ILogger logger)
{
Id = id;
_quicConnection = quicConnection;
_systemStream = systemStream;
_logger = new ContextLogger($"Connection-{id}", logger);
}
public static async Task<ClientConnection> OpenAsync(int id,
QuicConnection quicConnection, ILogger logger, CancellationToken ct)
{
var systemStream = await quicConnection.AcceptStreamAsync(QuicStreamType.Bidirectional, ct);
await systemStream.ReceivePingSendPong();
var clientConnection = new ClientConnection(id, quicConnection, systemStream, logger);
clientConnection.HandleRequestsAsync(ct);
return clientConnection;
}
private async void HandleRequestsAsync(CancellationToken ct)
{
try
{
while (!_connectionCts.IsCancellationRequested)
{
try
{
var header = await _systemStream.ReadDataMessageHeaderAsync(ct);
if(IsAuthorized)
HandleAuthorizedRequest(header);
else HandleUnauthorizedRequest(header);
}
catch (Exception ex)
{
_logger.LogWarn(ex);
}
}
await DisposeAsync();
}
catch (Exception ex)
{
_logger.LogError(ex);
}
}
private void HandleUnauthorizedRequest(DataMessageHeader header)
{
switch (header.type_code)
{
default:
throw new Exception($"New connection sent unexpected message: {header.type_code}");
case MessageTypeCode.RegistrationRequest:
// TODO: registration
break;
case MessageTypeCode.AuthorizationRequest:
// TODO: authorization
IsAuthorized = true;
break;
}
}
private void HandleAuthorizedRequest(DataMessageHeader header)
{
switch (header.type_code)
{
default:
throw new Exception($"New connection sent unexpected message: {header.type_code}");
}
}
public override int GetHashCode() => Id;
public async ValueTask DisposeAsync()
{
await _quicConnection.DisposeAsync();
}
}