2024-03-12 14:05:27 -04:00
|
|
|
using CommonSocketLibrary.Common;
|
|
|
|
using CommonSocketLibrary.Abstract;
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
2024-06-16 20:19:31 -04:00
|
|
|
using Serilog;
|
2024-03-12 14:05:27 -04:00
|
|
|
using TwitchChatTTS.Seven.Socket.Data;
|
|
|
|
using System.Text.Json;
|
|
|
|
|
|
|
|
namespace TwitchChatTTS.Seven.Socket
|
|
|
|
{
|
2024-06-16 20:19:31 -04:00
|
|
|
public class SevenSocketClient : WebSocketClient
|
|
|
|
{
|
2024-07-19 12:56:41 -04:00
|
|
|
private readonly User _user;
|
|
|
|
private readonly string[] _errorCodes;
|
|
|
|
private readonly int[] _reconnectDelay;
|
|
|
|
private string? URL;
|
|
|
|
|
|
|
|
public bool Connected { get; set; }
|
|
|
|
|
2024-03-12 14:05:27 -04:00
|
|
|
public SevenHelloMessage? ConnectionDetails { get; set; }
|
|
|
|
|
|
|
|
public SevenSocketClient(
|
2024-07-19 12:56:41 -04:00
|
|
|
User user,
|
|
|
|
[FromKeyedServices("7tv")] IEnumerable<IWebSocketHandler> handlers,
|
|
|
|
[FromKeyedServices("7tv")] MessageTypeManager<IWebSocketHandler> typeManager,
|
|
|
|
ILogger logger
|
|
|
|
) : base(handlers, typeManager, new JsonSerializerOptions()
|
2024-06-16 20:19:31 -04:00
|
|
|
{
|
2024-03-12 14:05:27 -04:00
|
|
|
PropertyNameCaseInsensitive = false,
|
|
|
|
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
|
2024-07-19 12:56:41 -04:00
|
|
|
}, logger)
|
2024-06-16 20:19:31 -04:00
|
|
|
{
|
2024-07-19 12:56:41 -04:00
|
|
|
_user = user;
|
2024-03-12 14:05:27 -04:00
|
|
|
ConnectionDetails = null;
|
2024-07-19 12:56:41 -04:00
|
|
|
|
|
|
|
_errorCodes = [
|
|
|
|
"Server Error",
|
|
|
|
"Unknown Operation",
|
|
|
|
"Invalid Payload",
|
|
|
|
"Auth Failure",
|
|
|
|
"Already Identified",
|
|
|
|
"Rate Limited",
|
|
|
|
"Restart",
|
|
|
|
"Maintenance",
|
|
|
|
"Timeout",
|
|
|
|
"Already Subscribed",
|
|
|
|
"Not Subscribed",
|
|
|
|
"Insufficient Privilege",
|
|
|
|
"Inactivity?"
|
|
|
|
];
|
|
|
|
_reconnectDelay = [
|
|
|
|
1000,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
0,
|
|
|
|
3000,
|
|
|
|
1000,
|
|
|
|
300000,
|
|
|
|
1000,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
1000,
|
|
|
|
1000
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Initialize()
|
|
|
|
{
|
|
|
|
_logger.Information("Initializing 7tv websocket client.");
|
|
|
|
OnConnected += (sender, e) =>
|
|
|
|
{
|
|
|
|
Connected = true;
|
|
|
|
_logger.Information("7tv websocket client connected.");
|
|
|
|
};
|
|
|
|
|
|
|
|
OnDisconnected += (sender, e) => OnDisconnection(sender, e);
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(_user.SevenEmoteSetId))
|
|
|
|
URL = $"{SevenApiClient.WEBSOCKET_URL}@emote_set.*<object_id={_user.SevenEmoteSetId}>";
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task Connect()
|
|
|
|
{
|
|
|
|
if (string.IsNullOrEmpty(URL))
|
|
|
|
{
|
|
|
|
_logger.Warning("Cannot find 7tv url. Not connecting to 7tv websockets.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(_user.SevenEmoteSetId))
|
|
|
|
{
|
|
|
|
_logger.Warning("Cannot find 7tv data for your channel. Not connecting to 7tv websockets.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_logger.Debug($"7tv client attempting to connect to {URL}");
|
2024-08-04 19:46:10 -04:00
|
|
|
try
|
|
|
|
{
|
|
|
|
await ConnectAsync(URL);
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
_logger.Error(ex, "Could not connect to 7tv websocket.");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Connected)
|
|
|
|
{
|
|
|
|
await Task.Delay(30000);
|
|
|
|
await Connect();
|
|
|
|
}
|
2024-07-19 12:56:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
private async void OnDisconnection(object? sender, SocketDisconnectionEventArgs e)
|
|
|
|
{
|
|
|
|
Connected = false;
|
|
|
|
|
|
|
|
if (int.TryParse(e.Reason, out int code))
|
|
|
|
{
|
|
|
|
if (code >= 0 && code < _errorCodes.Length)
|
|
|
|
_logger.Warning($"Received end of stream message for 7tv websocket [reason: {_errorCodes[code]}][code: {code}]");
|
|
|
|
else
|
|
|
|
_logger.Warning($"Received end of stream message for 7tv websocket [code: {code}]");
|
2024-08-04 19:46:10 -04:00
|
|
|
|
|
|
|
if (code < 0 || code >= _reconnectDelay.Length)
|
|
|
|
await Task.Delay(TimeSpan.FromSeconds(30));
|
|
|
|
else if (_reconnectDelay[code] < 0)
|
2024-07-19 12:56:41 -04:00
|
|
|
{
|
|
|
|
_logger.Error($"7tv client will remain disconnected due to a bad client implementation.");
|
|
|
|
return;
|
|
|
|
}
|
2024-08-04 19:46:10 -04:00
|
|
|
else if (_reconnectDelay[code] > 0)
|
2024-07-19 12:56:41 -04:00
|
|
|
await Task.Delay(_reconnectDelay[code]);
|
|
|
|
}
|
2024-08-04 19:46:10 -04:00
|
|
|
else {
|
|
|
|
_logger.Warning("Unknown 7tv disconnection.");
|
|
|
|
await Task.Delay(TimeSpan.FromSeconds(30));
|
2024-07-19 12:56:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
await Connect();
|
|
|
|
await Task.Delay(TimeSpan.FromMilliseconds(500));
|
|
|
|
|
|
|
|
if (Connected && ConnectionDetails?.SessionId != null)
|
|
|
|
{
|
|
|
|
await Send(34, new ResumeMessage() { SessionId = ConnectionDetails.SessionId });
|
|
|
|
_logger.Debug("Resumed connection to 7tv websocket.");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_logger.Debug("Resumed connection to 7tv websocket on a different session.");
|
|
|
|
}
|
2024-03-12 14:05:27 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|