2024-08-06 15:29:29 -04:00
using CommonSocketLibrary.Abstract ;
using Microsoft.Extensions.DependencyInjection ;
using Serilog ;
using TwitchChatTTS.Twitch.Socket.Messages ;
namespace TwitchChatTTS.Twitch.Socket
{
public interface ITwitchConnectionManager
{
TwitchWebsocketClient GetWorkingClient ( ) ;
TwitchWebsocketClient GetBackupClient ( ) ;
}
public class TwitchConnectionManager : ITwitchConnectionManager
{
private TwitchWebsocketClient ? _identified ;
private TwitchWebsocketClient ? _backup ;
private readonly IServiceProvider _serviceProvider ;
private readonly ILogger _logger ;
private readonly object _lock ;
public TwitchConnectionManager ( IServiceProvider serviceProvider , ILogger logger )
{
_serviceProvider = serviceProvider ;
_logger = logger ;
_lock = new object ( ) ;
}
public TwitchWebsocketClient GetBackupClient ( )
{
lock ( _lock )
{
if ( _identified = = null )
throw new InvalidOperationException ( "Cannot get backup Twitch client yet. Waiting for identification." ) ;
if ( _backup ! = null )
return _backup ;
return CreateNewClient ( ) ;
}
}
public TwitchWebsocketClient GetWorkingClient ( )
{
lock ( _lock )
{
if ( _identified = = null )
{
return CreateNewClient ( ) ;
}
return _identified ;
}
}
private TwitchWebsocketClient CreateNewClient ( )
{
if ( _backup ! = null )
return _backup ;
var client = ( _serviceProvider . GetRequiredKeyedService < SocketClient < TwitchWebsocketMessage > > ( "twitch-create" ) as TwitchWebsocketClient ) ! ;
client . Initialize ( ) ;
_backup = client ;
client . OnIdentified + = async ( s , e ) = >
{
bool clientDisconnect = false ;
lock ( _lock )
{
2024-08-06 19:31:35 -04:00
if ( _identified = = null | | _identified . ReceivedReconnecting )
2024-08-06 15:29:29 -04:00
{
2024-08-06 19:31:35 -04:00
if ( _backup ! = null & & _backup . UID = = client . UID )
{
_logger . Information ( $"Twitch client has been identified [client: {client.UID}][main: {_identified?.UID}][backup: {_backup.UID}]" ) ;
_identified = _backup ;
_backup = null ;
}
else
_logger . Warning ( $"Twitch client identified from unknown sources [client: {client.UID}][main: {_identified?.UID}][backup: {_backup?.UID}]" ) ;
2024-08-06 15:29:29 -04:00
}
2024-08-06 19:31:35 -04:00
else if ( _identified . UID = = client . UID )
2024-08-06 15:29:29 -04:00
{
2024-08-06 19:31:35 -04:00
_logger . Warning ( $"Twitch client has been re-identified [client: {client.UID}][main: {_identified.UID}][backup: {_backup?.UID}]" ) ;
2024-08-06 15:29:29 -04:00
}
2024-08-06 19:31:35 -04:00
else if ( _backup = = null | | _backup . UID ! = client . UID )
2024-08-06 15:29:29 -04:00
{
2024-08-06 19:31:35 -04:00
_logger . Warning ( $"Twitch client has been identified, but isn't main or backup [client: {client.UID}][main: {_identified.UID}][backup: {_backup?.UID}]" ) ;
clientDisconnect = true ;
2024-08-06 15:29:29 -04:00
}
}
if ( clientDisconnect )
await client . DisconnectAsync ( new SocketDisconnectionEventArgs ( "Closed" , "No need for a tertiary client." ) ) ;
} ;
2024-08-07 15:32:44 -04:00
client . OnDisconnected + = async ( s , e ) = >
2024-08-06 15:29:29 -04:00
{
2024-08-07 15:32:44 -04:00
bool reconnecting = false ;
2024-08-06 15:29:29 -04:00
lock ( _lock )
{
2024-08-06 19:31:35 -04:00
if ( _identified ? . UID = = client . UID )
2024-08-06 15:29:29 -04:00
{
2024-08-07 15:32:44 -04:00
_logger . Warning ( $"Identified Twitch client has disconnected [client: {client.UID}][main: {_identified.UID}][backup: {_backup?.UID}]" ) ;
2024-08-06 15:29:29 -04:00
_identified = null ;
2024-08-07 15:32:44 -04:00
reconnecting = true ;
2024-08-06 15:29:29 -04:00
}
2024-08-06 19:31:35 -04:00
else if ( _backup ? . UID = = client . UID )
2024-08-06 15:29:29 -04:00
{
2024-08-07 15:32:44 -04:00
_logger . Warning ( $"Backup Twitch client has disconnected [client: {client.UID}][main: {_identified?.UID}][backup: {_backup.UID}]" ) ;
2024-08-06 15:29:29 -04:00
_backup = null ;
}
2024-08-06 19:31:35 -04:00
else if ( client . ReceivedReconnecting )
{
_logger . Debug ( $"Twitch client disconnected due to reconnection [client: {client.UID}][main: {_identified?.UID}][backup: {_backup?.UID}]" ) ;
}
2024-08-06 15:29:29 -04:00
else
2024-08-06 19:31:35 -04:00
_logger . Error ( $"Twitch client disconnected from unknown source [client: {client.UID}][main: {_identified?.UID}][backup: {_backup?.UID}]" ) ;
2024-08-06 15:29:29 -04:00
}
2024-08-07 15:32:44 -04:00
if ( reconnecting )
{
var client = GetWorkingClient ( ) ;
await client . Connect ( ) ;
}
2024-08-06 15:29:29 -04:00
} ;
_logger . Debug ( "Created a Twitch websocket client." ) ;
return client ;
}
}
}