Fixed 7tv & Twitch reconnection. Added adbreak, follow, subscription handlers for Twitch. Added multi-chat support. Added support to unsubscribe from Twitch event subs.
This commit is contained in:
		
							
								
								
									
										119
									
								
								Twitch/Socket/TwitchConnectionManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								Twitch/Socket/TwitchConnectionManager.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
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)
 | 
			
		||||
                {
 | 
			
		||||
                    if (_identified == client)
 | 
			
		||||
                    {
 | 
			
		||||
                        _logger.Error("Twitch client has been re-identified.");
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (_backup != client)
 | 
			
		||||
                    {
 | 
			
		||||
                        _logger.Warning("Twitch client has been identified, but isn't backup. Disconnecting.");
 | 
			
		||||
                        clientDisconnect = true;
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (_identified != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    _identified = _backup;
 | 
			
		||||
                    _backup = null;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (clientDisconnect)
 | 
			
		||||
                    await client.DisconnectAsync(new SocketDisconnectionEventArgs("Closed", "No need for a tertiary client."));
 | 
			
		||||
 | 
			
		||||
                _logger.Information("Twitch client has been identified.");
 | 
			
		||||
            };
 | 
			
		||||
            client.OnDisconnected += (s, e) =>
 | 
			
		||||
            {
 | 
			
		||||
                lock (_lock)
 | 
			
		||||
                {
 | 
			
		||||
                    if (_identified == client)
 | 
			
		||||
                    {
 | 
			
		||||
                        _identified = null;
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (_backup == client)
 | 
			
		||||
                    {
 | 
			
		||||
                        _backup = null;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                        _logger.Error("Twitch client disconnection from unknown source.");
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            _logger.Debug("Created a Twitch websocket client.");
 | 
			
		||||
            return client;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user