private async void TwitchClient_OnDisconnected(object sender, OnDisconnectedEventArgs e) { if (_isStopping) { _logger.LogInformation("Disconnected!"); return; } // wait until it's *really* disconnected while (_client.IsConnected) { } _logger.LogInformation("Client disconnected unexpectedly!"); // refresh tokens and reconnect to chat _tokens = await _mediator.Send(new RefreshTokensRequest()); await _client.ReconnectAsync(accessToken : _tokens.AccessToken); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { // get and keep the latest auth tokens using (var context = _contextFactory.CreateDbContext()) { _tokens = context.AccessTokens.OrderByDescending(a => a.CreatedOn).First(); } // validate our tokens and refresh if necessary var api = _apiFactory.CreateApiClient(); var response = await api.VerifyAccessTokenAsync(_tokens.AccessToken); if (response is null) { _tokens = await _mediator.Send(new RefreshTokensRequest(), stoppingToken); } // hook up events _client.OnDisconnected += TwitchClient_OnDisconnected; // connect to Twitch _logger.LogInformation("Connecting to Twitch..."); await _client.ConnectAsync(_settings.BotUsername, _tokens.AccessToken, token : stoppingToken); // continue to read messages until the application stops while (!stoppingToken.IsCancellationRequested) { var message = await _client.ReadMessageAsync(stoppingToken); using (_logger.BeginScope(new Dictionary <string, object> { ["@TwitchMessage"] = message })) { try { switch (message) { case TwitchMessage.Welcome: _logger.LogInformation("Connected!"); await TwitchClient_OnConnected(); break; case TwitchMessage.Join join: _logger.LogDebug("User {UserName} has joined channel {ChannelName}.", join.Username, join.Channel); break; case TwitchMessage.Chat chat: await TwitchClient_OnMessageReceived(chat); break; case TwitchMessage.ClearChat clearChat: var channelId = await _userService.GetIdByUsername(clearChat.Channel); if (string.IsNullOrWhiteSpace(clearChat.User)) { // todo: clear the entire channel's history } else { _logger.LogInformation("Banning user {UserName} from channel {ChannelName}.", clearChat.User, clearChat.Channel); await _mediator.Send(new BanUserRequest(clearChat.Channel, clearChat.User), stoppingToken); } break; case TwitchMessage.ClearMsg clearMsg: await _mediator.Send(new DeleteMessageNotification(clearMsg.TargetMessageId), stoppingToken); break; case TwitchMessage.GiftSub giftSub: await TwitchClient_OnGiftedSubscription(giftSub); break; case TwitchMessage.Part part: _logger.LogDebug("User {UserName} has left channel {ChannelName}.", part.Username, part.Channel); break; } } catch (Exception e) { _logger.LogError(e, "Exception caught in message read loop after receiving {MessageType}.", message.GetType()); } } } _isStopping = true; _logger.LogInformation("Disconnecting from Twitch..."); }