Meum/Meum.Server/Server.cs
2025-05-09 16:32:35 +05:00

66 lines
2.4 KiB
C#

using System.Net;
using System.Net.Quic;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using DTLib.Logging;
namespace Meum.Server;
public class Server
{
private readonly ServerConfig _config;
private readonly X509Certificate _certificate;
private readonly ILogger _logger;
private QuicListener? _listener;
public Server(ServerConfig config, ILogger logger, X509Certificate? certificate = null)
{
_config = config;
_logger = logger;
_certificate = certificate ??
X509Certificate2.CreateFromPemFile(config.certificate_path, config.key_path);
}
public async ValueTask ListenAsync()
{
var serverConnectionOptions = new QuicServerConnectionOptions
{
DefaultStreamErrorCode = Constants.DefaultStreamErrorCode,
DefaultCloseErrorCode = Constants.DefaultCloseErrorCode,
ServerAuthenticationOptions = new SslServerAuthenticationOptions
{
ApplicationProtocols = Constants.ApplicationProtocols,
ServerCertificate = _certificate,
ClientCertificateRequired = false
}
};
var listenerOptions = new QuicListenerOptions
{
ListenEndPoint = new IPEndPoint(IPAddress.Parse(_config.listener_ip), _config.listener_port),
ApplicationProtocols = Constants.ApplicationProtocols,
ConnectionOptionsCallback = (_, _, _) => ValueTask.FromResult(serverConnectionOptions)
};
_listener = await QuicListener.ListenAsync(listenerOptions);
}
public async Task<ClientConnection> AcceptConnectionAsync(CancellationToken ct = default)
{
if (_listener == null)
throw new Exception("Server is not listening");
while (true)
{
ct.ThrowIfCancellationRequested();
var quicConnection = await _listener.AcceptConnectionAsync(ct);
var timeOutCts = CancellationTokenSource.CreateLinkedTokenSource(ct);
timeOutCts.CancelAfter(Constants.ConnectionTimeout);
var clientConnection = await ClientConnection.OpenAsync(
quicConnection,
_logger,
timeOutCts.Token);
return clientConnection;
}
}
}