From 743d401309faac33d624ec6027fb14fd7932c4ed Mon Sep 17 00:00:00 2001 From: Pavel Gromov Date: Sun, 26 Nov 2023 19:09:05 +0100 Subject: [PATCH] Build fix --- Directory.Packages.props | 2 +- Telegrom.Core/Contexts/SessionManager.cs | 17 +-- Telegrom.Core/ITelegramUpdateReceiver.cs | 6 +- Telegrom.Core/IWakeUpService.cs | 2 +- Telegrom.Database/Model/IdentityState.cs | 2 +- Telegrom.Database/Model/IdentityUser.cs | 2 +- Telegrom.Database/Model/SessionAttribute.cs | 2 +- Telegrom.Database/Model/SessionUpdate.cs | 2 +- Telegrom.Database/WakeUpService.cs | 2 +- .../TelegramServiceModule.cs | 136 ++++++++++++------ .../TelegramUpdateReceiver.cs | 43 +++--- .../Telegrom.TelegramService.csproj | 2 +- Telegrom/InternalBotService.cs | 11 +- 13 files changed, 138 insertions(+), 91 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 02a5984..5c50123 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,7 +5,6 @@ - @@ -20,6 +19,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Telegrom.Core/Contexts/SessionManager.cs b/Telegrom.Core/Contexts/SessionManager.cs index 108a941..7d9f8de 100644 --- a/Telegrom.Core/Contexts/SessionManager.cs +++ b/Telegrom.Core/Contexts/SessionManager.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Autofac; +using Autofac; using Telegram.Bot.Types; namespace Telegrom.Core.Contexts @@ -12,9 +7,9 @@ public sealed class SessionManager : IAsyncDisposable { private readonly ILifetimeScope _lifetimeScope; private readonly IIdentityService _identityService; - private readonly object _syncRoot = new object(); - private readonly LinkedList _recentSessionContextsQueue = new LinkedList(); - private readonly Dictionary _sessionContexts = new Dictionary(); + private readonly object _syncRoot = new(); + private readonly LinkedList _recentSessionContextsQueue = []; + private readonly Dictionary _sessionContexts = new(); private readonly int _maxActiveSessions; public SessionManager(ILifetimeScope lifetimeScope, IIdentityService identityService, int maxActiveSessions) @@ -65,9 +60,9 @@ public async Task GetSessionContextAsync(User user, Cancellation return sessionContext; } - public async Task CompleteAllAsync() + public Task CompleteAllAsync() { - await Task.WhenAll(_sessionContexts.Values.Select(sessionContext => sessionContext.Complete())); + return Task.WhenAll(_sessionContexts.Values.Select(sessionContext => sessionContext.Complete())); } public async ValueTask DisposeAsync() diff --git a/Telegrom.Core/ITelegramUpdateReceiver.cs b/Telegrom.Core/ITelegramUpdateReceiver.cs index 6fd77a9..30706ce 100644 --- a/Telegrom.Core/ITelegramUpdateReceiver.cs +++ b/Telegrom.Core/ITelegramUpdateReceiver.cs @@ -4,9 +4,9 @@ namespace Telegrom.Core { - public interface ITelegramUpdateReceiver : IDisposable + public interface ITelegramUpdateReceiver { - void Start(); - void SetUpdateReceivedHandler(Action handler); + void Start(CancellationToken cancellationToken); + void SetUpdateReceivedHandler(Func handler); } } diff --git a/Telegrom.Core/IWakeUpService.cs b/Telegrom.Core/IWakeUpService.cs index 65be1a5..51f8eb4 100644 --- a/Telegrom.Core/IWakeUpService.cs +++ b/Telegrom.Core/IWakeUpService.cs @@ -7,6 +7,6 @@ namespace Telegrom.Core { public interface IWakeUpService { - Task WakeUpAsync(Action handler, CancellationToken cancellationToken); + Task WakeUpAsync(Func handler, CancellationToken cancellationToken); } } diff --git a/Telegrom.Database/Model/IdentityState.cs b/Telegrom.Database/Model/IdentityState.cs index e6dcd97..ce1568e 100644 --- a/Telegrom.Database/Model/IdentityState.cs +++ b/Telegrom.Database/Model/IdentityState.cs @@ -6,7 +6,7 @@ namespace Telegrom.Database.Model public sealed class IdentityState { [DatabaseGenerated(DatabaseGeneratedOption.None)] - public int IdentityId { get; set; } + public long IdentityId { get; set; } public string StateName { get; set; } public byte[] RowVersion { get; set; } } diff --git a/Telegrom.Database/Model/IdentityUser.cs b/Telegrom.Database/Model/IdentityUser.cs index 27ed018..fa2bf82 100644 --- a/Telegrom.Database/Model/IdentityUser.cs +++ b/Telegrom.Database/Model/IdentityUser.cs @@ -6,7 +6,7 @@ namespace Telegrom.Database.Model public sealed class IdentityUser { [DatabaseGenerated(DatabaseGeneratedOption.None)] - public int Id { get; set; } + public long Id { get; set; } public string Username { get; set; } public string FirstName { get; set; } public string LastName { get; set; } diff --git a/Telegrom.Database/Model/SessionAttribute.cs b/Telegrom.Database/Model/SessionAttribute.cs index 5c53793..410e3cc 100644 --- a/Telegrom.Database/Model/SessionAttribute.cs +++ b/Telegrom.Database/Model/SessionAttribute.cs @@ -9,7 +9,7 @@ public sealed class SessionAttribute [DatabaseGenerated(DatabaseGeneratedOption.None)] public Guid Id { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.None)] - public int SessionId { get; set; } + public long SessionId { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.None)] public string Type { get; set; } public string Value { get; set; } diff --git a/Telegrom.Database/Model/SessionUpdate.cs b/Telegrom.Database/Model/SessionUpdate.cs index 19bc0db..84a0554 100644 --- a/Telegrom.Database/Model/SessionUpdate.cs +++ b/Telegrom.Database/Model/SessionUpdate.cs @@ -6,7 +6,7 @@ namespace Telegrom.Database.Model public sealed class SessionUpdate { [DatabaseGenerated(DatabaseGeneratedOption.None)] - public int IdentityId { get; set; } + public long IdentityId { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.None)] public int UpdateId { get; set; } public string UpdateType { get; set; } diff --git a/Telegrom.Database/WakeUpService.cs b/Telegrom.Database/WakeUpService.cs index df5a687..d9034f3 100644 --- a/Telegrom.Database/WakeUpService.cs +++ b/Telegrom.Database/WakeUpService.cs @@ -18,7 +18,7 @@ public WakeUpService(DbContextOptions dbContextOptions) _dbContextOptions = dbContextOptions; } - public async Task WakeUpAsync(Action handler, CancellationToken cancellationToken) + public async Task WakeUpAsync(Func handler, CancellationToken cancellationToken) { await using var context = new DatabaseContext(_dbContextOptions); var notProcessedUpdates = await context.SessionUpdates diff --git a/Telegrom.TelegramService/TelegramServiceModule.cs b/Telegrom.TelegramService/TelegramServiceModule.cs index dab1724..01ecd12 100644 --- a/Telegrom.TelegramService/TelegramServiceModule.cs +++ b/Telegrom.TelegramService/TelegramServiceModule.cs @@ -1,58 +1,104 @@ using System.Net; using Autofac; -using MihaZupan; +using Microsoft.Extensions.DependencyInjection; using Telegram.Bot; using Telegrom.Core; +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -namespace Telegrom.TelegramService +namespace Telegrom.TelegramService; + +public sealed class TelegramServiceModule : Module { - public class TelegramServiceModule : Module + private const string HttpClientName = "typicode"; + + protected override void Load(ContainerBuilder builder) { - protected override void Load(ContainerBuilder builder) + var proxy = CreateProxy(); + + builder.Register(ctx => { - if (!string.IsNullOrEmpty(TelegramOptions.Current.ProxyAddress)) - { - builder.RegisterInstance(new TelegramBotClient( - TelegramOptions.Current.TelegramApiToken, - new WebProxy(TelegramOptions.Current.ProxyAddress) - { - UseDefaultCredentials = true - })) - .AsImplementedInterfaces() - .SingleInstance(); - } - else if (!string.IsNullOrEmpty(TelegramOptions.Current.Socks5HostName) - && TelegramOptions.Current.Socks5Port.HasValue) - { - HttpToSocks5Proxy proxy; - if (!string.IsNullOrEmpty(TelegramOptions.Current.Socks5Username) - && !string.IsNullOrEmpty(TelegramOptions.Current.Socks5Password)) - { - proxy = new HttpToSocks5Proxy( - TelegramOptions.Current.Socks5HostName, - TelegramOptions.Current.Socks5Port.Value, - TelegramOptions.Current.Socks5Username, - TelegramOptions.Current.Socks5Password); - } - else + var services = new ServiceCollection(); + services.AddHttpClient(HttpClientName) + .ConfigurePrimaryHttpMessageHandler(() => { - proxy = new HttpToSocks5Proxy(TelegramOptions.Current.Socks5HostName, TelegramOptions.Current.Socks5Port.Value); - } - - builder.RegisterInstance(new TelegramBotClient(TelegramOptions.Current.TelegramApiToken, proxy)) - .AsImplementedInterfaces() - .SingleInstance(); - } - else + var handler = new SocketsHttpHandler(); + if (proxy != null) + { + handler.Proxy = proxy; + handler.UseProxy = true; + } + return handler; + }); + + var provider = services.BuildServiceProvider(); + return provider.GetRequiredService(); + }).SingleInstance(); + + builder.Register(c => { - builder.RegisterInstance(new TelegramBotClient(TelegramOptions.Current.TelegramApiToken)) - .AsImplementedInterfaces() - .SingleInstance(); - } - - builder.RegisterType() - .As() - .SingleInstance(); + var httpClientFactory = c.Resolve(); + var httpClient = httpClientFactory.CreateClient(HttpClientName); + return new TelegramBotClient(TelegramOptions.Current.TelegramApiToken, httpClient); + }) + .AsImplementedInterfaces() + .SingleInstance(); + + builder.RegisterType() + .As() + .SingleInstance(); + } + + private static WebProxy? CreateProxy() + { + if (IsHttpProxyConfigured()) + { + return CreateHttpProxy(); + } + + if (IsSocks5ProxyConfigured()) + { + return CreateSocks5Proxy(); + } + + return null; + } + + private static bool IsHttpProxyConfigured() + { + return !string.IsNullOrEmpty(TelegramOptions.Current.ProxyAddress); + } + + private static WebProxy CreateHttpProxy() + { + return new WebProxy(TelegramOptions.Current.ProxyAddress) + { + UseDefaultCredentials = true + }; + } + + private static bool IsSocks5ProxyConfigured() + { + return !string.IsNullOrEmpty(TelegramOptions.Current.Socks5HostName) + && TelegramOptions.Current.Socks5Port.HasValue; + } + + private static WebProxy CreateSocks5Proxy() + { + var socks5Proxy = new WebProxy(TelegramOptions.Current.Socks5HostName, + TelegramOptions.Current.Socks5Port.Value); + + if (IsSocks5CredentialsConfigured()) + { + socks5Proxy.Credentials = new NetworkCredential(TelegramOptions.Current.Socks5Username, + TelegramOptions.Current.Socks5Password); } + + return socks5Proxy; + } + + private static bool IsSocks5CredentialsConfigured() + { + return !string.IsNullOrEmpty(TelegramOptions.Current.Socks5Username) + && !string.IsNullOrEmpty(TelegramOptions.Current.Socks5Password); } } diff --git a/Telegrom.TelegramService/TelegramUpdateReceiver.cs b/Telegrom.TelegramService/TelegramUpdateReceiver.cs index 850abf6..1f83c56 100644 --- a/Telegrom.TelegramService/TelegramUpdateReceiver.cs +++ b/Telegrom.TelegramService/TelegramUpdateReceiver.cs @@ -1,18 +1,17 @@ -using System; -using System.Threading; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Telegram.Bot; -using Telegram.Bot.Args; +using Telegram.Bot.Polling; using Telegram.Bot.Types; using Telegrom.Core; namespace Telegrom.TelegramService { - public class TelegramUpdateReceiver : ITelegramUpdateReceiver + public class TelegramUpdateReceiver : ITelegramUpdateReceiver, IDisposable { private readonly ITelegramBotClient _telegramBotClient; private readonly ILogger _logger; - private Action _updateReceivedHandler; + private Func? _updateReceivedHandler; + private CancellationTokenSource _cts; public TelegramUpdateReceiver(ITelegramBotClient telegramBotClient, ILogger logger) @@ -23,34 +22,40 @@ public TelegramUpdateReceiver(ITelegramBotClient telegramBotClient, var me = _telegramBotClient.GetMeAsync().GetAwaiter().GetResult(); _logger.LogInformation($"Hello, World! I am identityUser {me.Id} and my name is {me.FirstName}."); } - - public void Start() + + public void SetUpdateReceivedHandler(Func handler) { - RegisterHandlers(); - _telegramBotClient.StartReceiving(); + _updateReceivedHandler = handler; } - private void RegisterHandlers() + public void Start(CancellationToken cancellationToken) { - _telegramBotClient.OnUpdate += BotOnUpdateReceived; + _cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + var receiverOptions = new ReceiverOptions(); + + _telegramBotClient.StartReceiving(HandleUpdateAsync, HandleErrorAsync, receiverOptions, _cts.Token); } - private void BotOnUpdateReceived(object sender, UpdateEventArgs e) + private async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken) { - var update = e.Update; _logger.LogInformation("Get update {@update}", update); - _updateReceivedHandler?.Invoke(update, default); + if (_updateReceivedHandler != null) + { + await _updateReceivedHandler(update, cancellationToken); + } } - - public void SetUpdateReceivedHandler(Action handler) + + private Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken) { - _updateReceivedHandler = handler; + _logger.LogError("An error occurred in receiving updates: {Exception}", exception); + return Task.CompletedTask; } public void Dispose() { - _telegramBotClient.StopReceiving(); + _cts.Cancel(); + _logger.LogInformation("Receiver stopped"); } } } diff --git a/Telegrom.TelegramService/Telegrom.TelegramService.csproj b/Telegrom.TelegramService/Telegrom.TelegramService.csproj index 509710b..be1fed9 100644 --- a/Telegrom.TelegramService/Telegrom.TelegramService.csproj +++ b/Telegrom.TelegramService/Telegrom.TelegramService.csproj @@ -2,7 +2,7 @@ - + diff --git a/Telegrom/InternalBotService.cs b/Telegrom/InternalBotService.cs index 718792f..58a5c49 100644 --- a/Telegrom/InternalBotService.cs +++ b/Telegrom/InternalBotService.cs @@ -11,6 +11,7 @@ namespace Telegrom internal class InternalBotService { private readonly SessionManager _sessionManager; + private readonly ITelegramUpdateReceiver _telegramUpdateReceiver; private readonly IUpdateDispatcher _updateDispatcher; private readonly IRequestDispatcher _requestDispatcher; private readonly IWakeUpService _wakeUpService; @@ -24,27 +25,27 @@ public InternalBotService(SessionManager sessionManager, ILogger logger) { _sessionManager = sessionManager; + _telegramUpdateReceiver = telegramUpdateReceiver; _updateDispatcher = updateDispatcher; _requestDispatcher = requestDispatcher; _wakeUpService = wakeUpService; _logger = logger; - - telegramUpdateReceiver.SetUpdateReceivedHandler(HandleTelegramMessageReceived); - telegramUpdateReceiver.Start(); } public async Task RunAsync(CancellationToken cancellationToken) { _logger.LogInformation("InternalBotService started"); + _telegramUpdateReceiver.SetUpdateReceivedHandler(HandleTelegramMessageReceived); + _telegramUpdateReceiver.Start(cancellationToken); _ = _updateDispatcher.RunAsync(cancellationToken); await _wakeUpService.WakeUpAsync(HandleTelegramMessageReceived, cancellationToken); await _requestDispatcher.RunAsync(cancellationToken); await _sessionManager.CompleteAllAsync(); } - public async void HandleTelegramMessageReceived(Update update, CancellationToken cancellationToken) + private Task HandleTelegramMessageReceived(Update update, CancellationToken cancellationToken) { - await _updateDispatcher.DispatchAsync(update, cancellationToken); + return _updateDispatcher.DispatchAsync(update, cancellationToken); } } }