2025-05-13 09:54:38 -05:00
|
|
|
namespace StevesBot.Worker.Discord;
|
|
|
|
|
|
|
|
|
|
internal class DiscordGatewayClient : IDiscordGatewayClient
|
|
|
|
|
{
|
|
|
|
|
private readonly DiscordGatewayClientOptions _options;
|
|
|
|
|
private readonly IWebSocketFactory _webSocketFactory;
|
|
|
|
|
private readonly ILogger<DiscordGatewayClient> _logger;
|
2025-05-13 15:55:50 -05:00
|
|
|
private readonly IDiscordRestClient _discordRestClient;
|
|
|
|
|
// private readonly JsonSerializerOptions _jsonSerializerOptions = new()
|
|
|
|
|
// {
|
|
|
|
|
// PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
|
|
|
// ReferenceHandler = ReferenceHandler.IgnoreCycles,
|
|
|
|
|
// Converters =
|
|
|
|
|
// {
|
|
|
|
|
// new DiscordEventConverter(),
|
|
|
|
|
// },
|
|
|
|
|
// };
|
2025-05-13 09:54:38 -05:00
|
|
|
private readonly AsyncLock _lock = new();
|
|
|
|
|
|
|
|
|
|
private string _gatewayUrl = string.Empty;
|
|
|
|
|
private IWebSocket? _webSocket;
|
|
|
|
|
private Task? _receiveTask;
|
2025-05-13 15:55:50 -05:00
|
|
|
// private DateTime _timeLastHeartbeatSent = DateTime.MinValue;
|
|
|
|
|
// private DateTime _timeLastHeartbeatAcknowledged = DateTime.MinValue;
|
|
|
|
|
// private CancellationTokenSource? _heartbeatCts;
|
|
|
|
|
// private Task? _heartbeatTask;
|
|
|
|
|
// private string _sessionId = string.Empty;
|
|
|
|
|
// private string _resumeGatewayUrl = string.Empty;
|
2025-05-13 09:54:38 -05:00
|
|
|
|
|
|
|
|
public DiscordGatewayClient(
|
|
|
|
|
DiscordGatewayClientOptions options,
|
|
|
|
|
IWebSocketFactory webSocketFactory,
|
2025-05-13 15:55:50 -05:00
|
|
|
ILogger<DiscordGatewayClient> logger,
|
|
|
|
|
IDiscordRestClient discordRestClient
|
2025-05-13 09:54:38 -05:00
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
_options = options ?? throw new ArgumentNullException(nameof(options));
|
|
|
|
|
_webSocketFactory = webSocketFactory ?? throw new ArgumentNullException(nameof(webSocketFactory));
|
|
|
|
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
2025-05-13 15:55:50 -05:00
|
|
|
_discordRestClient = discordRestClient ?? throw new ArgumentNullException(nameof(discordRestClient));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task ConnectAsync(CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
using (await _lock.LockAsync(cancellationToken))
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(_gatewayUrl))
|
|
|
|
|
{
|
|
|
|
|
_gatewayUrl = await _discordRestClient.GetGatewayUrlAsync(cancellationToken);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_webSocket = _webSocketFactory.Create();
|
|
|
|
|
|
|
|
|
|
var uri = new Uri(_gatewayUrl);
|
|
|
|
|
await _webSocket.ConnectAsync(uri, cancellationToken);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("Connected to Discord Gateway at {GatewayUrl}", _gatewayUrl);
|
|
|
|
|
|
|
|
|
|
_receiveTask = ReceiveMessagesAsync(cancellationToken);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Task ReceiveMessagesAsync(CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
return Task.CompletedTask;
|
2025-05-13 09:54:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
2025-05-13 15:55:50 -05:00
|
|
|
// _heartbeatCts?.Cancel();
|
|
|
|
|
// _heartbeatCts?.Dispose();
|
|
|
|
|
// _heartbeatTask?.Dispose();
|
2025-05-13 09:54:38 -05:00
|
|
|
_receiveTask?.Dispose();
|
|
|
|
|
_webSocket?.Dispose();
|
2025-05-13 15:55:50 -05:00
|
|
|
_lock.Dispose();
|
2025-05-13 09:54:38 -05:00
|
|
|
}
|
|
|
|
|
}
|