Exemple #1
0
        private async Task TwitchHandshake(ClientWebSocket webSocket, CancellationToken cancellationToken,
                                           TwitchService twitchService, TwitchManager twitchManager)
        {
            await CheckToken(cancellationToken, twitchService);

            var token = await twitchService.GetToken();

            var user = await twitchManager.GetUser();

            Send($"PASS oauth:{token.access_token}");
            Send($"NICK {user.login}"); // TODO: get nick from twitch API
        }
Exemple #2
0
        private async Task Receive(ClientWebSocket webSocket, CancellationToken cancellationToken, TwitchService twitchService,
                                   TwitchManager twitchManager, AccessToken accessToken)
        {
            if (webSocket.State != WebSocketState.Open)
            {
                throw new InvalidOperationException($"[TwitchBackgroundService] Twitch socket {webSocket.State.ToString()}");
            }
            var user = await twitchManager.GetUser();

            var encoder = new UTF8Encoding();
            var partial = string.Empty;

            while (webSocket.State == WebSocketState.Open &&
                   !cancellationToken.IsCancellationRequested &&
                   await twitchService.IsEnabled() &&
                   accessToken.Status == AccessTokenStatus.Ok)
            {
                var buffer = new byte[receiveChunkSize];
                logger.LogDebug($"[TwitchBackgroundService] Listening to socket");
                var result = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), cancellationToken);

                logger.LogDebug($"[TwitchBackgroundService] Receive status {result.MessageType}");

                if (result.MessageType == WebSocketMessageType.Close)
                {
                    await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, cancellationToken);
                }
                else if (result.MessageType == WebSocketMessageType.Text)
                {
                    var text = partial + encoder.GetString(buffer).Replace("\0", "");
                    partial = string.Empty;

                    if (string.IsNullOrEmpty(text))
                    {
                        continue;
                    }

                    var lines = (text.Substring(0, text.LastIndexOf('\r'))).Split('\r');

                    foreach (var line in lines)
                    {
                        //logger.LogDebug($"[TwitchBackgroundService] Twitch Chat < {line}");

                        if (line.Contains("PING"))
                        {
                            var host = line.Substring(line.IndexOf(':'));
                            Send($"PONG :{host}");
                            await UpdateDashboardStatus(IntegrationStatus.Connected,
                                                        cancellationToken);

                            continue;
                        }

                        await twitchService.ProcessMessage(line);
                    }

                    partial = text.Substring(text.LastIndexOf('\r'));
                }

                await Task.Delay(delay, cancellationToken);
            }
        }
Exemple #3
0
        private async Task <AccessToken> CheckToken(CancellationToken cancellationToken, TwitchService twitchService)
        {
            var token = await twitchService.GetToken();

            if (token == null)
            {
                await UpdateDashboardStatus(IntegrationStatus.Forbidden, cancellationToken);

                return(null);
            }

            if (token.Status == AccessTokenStatus.Expired && token.HasRefreshToken)
            {
                await twitchService.RefreshToken(token);
            }

            if (token.Status != AccessTokenStatus.Ok)
            {
                await UpdateDashboardStatus(IntegrationStatus.Forbidden, cancellationToken);

                return(null);
            }

            return(token);
        }
Exemple #4
0
        protected override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            cancellationToken.Register(() =>
            {
                logger.LogDebug($"TwitchBackgroundService background task is stopping.");
            });

            delay = defaultDelay;

            using (var scope = serviceScopeFactory.CreateScope())
            {
                twitchService    = scope.ServiceProvider.GetRequiredService <TwitchService>();
                dashboardService = scope.ServiceProvider.GetRequiredService <DashboardService>();

                while (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        if (!await twitchService.IsEnabled())
                        {
                            await dashboardService.UpdateStatus(ApiSource.Twitch, BackgroundServiceStatus.Disabled,
                                                                cancellationToken);

                            await Task.Delay(delay, cancellationToken);

                            continue;
                        }

                        if (!twitchService.IsConfigured())
                        {
                            await dashboardService.UpdateStatus(ApiSource.Twitch, BackgroundServiceStatus.NotConfigured,
                                                                cancellationToken);

                            await Task.Delay(delay, cancellationToken);

                            continue;
                        }

                        var webSocket = new ClientWebSocket();
                        if (webSocket.State != WebSocketState.Open)
                        {
                            await webSocket.ConnectAsync(new Uri("wss://irc-ws.chat.twitch.tv:443"), cancellationToken);

                            var timeout = 0;
                            while (webSocket.State == WebSocketState.Connecting && timeout < connectionTimeout &&
                                   !cancellationToken.IsCancellationRequested)
                            {
                                await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);

                                timeout++;
                            }

                            if (webSocket.State == WebSocketState.Open)
                            {
                                await TwitchHandshake(webSocket, cancellationToken);
                            }
                        }

                        while (!cancellationToken.IsCancellationRequested && await twitchService.IsEnabled())
                        {
                            await dashboardService.UpdateStatus(ApiSource.Twitch, BackgroundServiceStatus.Connected,
                                                                cancellationToken);
                            await Send(webSocket, cancellationToken, "JOIN :#machacoder");
                            await Receive(webSocket, cancellationToken);
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex.GetBaseException(), ex.GetBaseException().Message);
                        await dashboardService.UpdateStatus(ApiSource.Twitch, "Error", cancellationToken);
                    }

                    await Task.Delay(delay, cancellationToken);
                }
            }
        }