93 lines
2.9 KiB
C#
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();
|
|
}
|
|
} |