Mq Consumer

This commit is contained in:
Mikhail Trubnikov
2023-09-21 15:21:33 +10:00
parent 096a990669
commit c7acfd153d
12 changed files with 211 additions and 15 deletions

View File

@@ -3,6 +3,7 @@ using PARR.BLL.Contracts.Interfaces;
using PARR.BLL.Domain.Mq; using PARR.BLL.Domain.Mq;
using PARR.BLL.Services.Interfaces; using PARR.BLL.Services.Interfaces;
using RabbitMQ.Client; using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text; using System.Text;
namespace PARR.BLL.Services.Implementations namespace PARR.BLL.Services.Implementations
@@ -11,6 +12,8 @@ namespace PARR.BLL.Services.Implementations
{ {
private readonly ILogger<MqService> logger; private readonly ILogger<MqService> logger;
public event ReceivedHandler? Received;
public MqService(ILogger<MqService> logger) public MqService(ILogger<MqService> logger)
{ {
this.logger = logger; this.logger = logger;
@@ -83,5 +86,61 @@ namespace PARR.BLL.Services.Implementations
return new MqSendResult { IsSuccess = false, NotSendMessages = notSendMsg.ToArray() }; return new MqSendResult { IsSuccess = false, NotSendMessages = notSendMsg.ToArray() };
} }
} }
//TODO: rename ListenQueue
public void InitConsumer(IMqSettings mqSettings)
{
logger.LogInformation($"Устанавливаю соединение с RabbitMQ: {mqSettings.HostName}, {mqSettings.QueueName}");
var facory = new ConnectionFactory
{
HostName = mqSettings.HostName,
UserName = mqSettings.User,
Password = mqSettings.Password,
AutomaticRecoveryEnabled = true,
DispatchConsumersAsync = true
};
try
{
var connection = facory.CreateConnection();
var channel = connection.CreateModel();
var args = new Dictionary<string, object> { { "x-queue-mode", "lazy" } };
channel.QueueDeclare(
queue: mqSettings.QueueName,
durable: true,
exclusive: false,
autoDelete: false,
arguments: args
);
logger.LogInformation($"Соединение с RabbitMQ установлено: {mqSettings.HostName}, {mqSettings.QueueName}");
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.Received += async (ch, ea) =>
{
var content = Encoding.UTF8.GetString(ea.Body.ToArray());
logger.LogDebug($"Получено сообщение: {content}");
//https://metanit.com/sharp/tutorial/3.14.php
Received?.Invoke(content);
channel.BasicAck(ea.DeliveryTag, false);
await Task.Yield();
};
channel.BasicConsume(mqSettings.QueueName, false, consumer);
}
catch (Exception ex)
{
logger.LogError(ex, $"Ошибка при получении сообщений из очереди: {mqSettings.HostName}, {mqSettings.QueueName}");
}
}
} }
} }

View File

@@ -3,8 +3,13 @@ using PARR.BLL.Domain.Mq;
namespace PARR.BLL.Services.Interfaces namespace PARR.BLL.Services.Interfaces
{ {
public delegate void ReceivedHandler(string msg);
public interface IMqService public interface IMqService
{ {
event ReceivedHandler? Received;
void InitConsumer(IMqSettings mqSettings);
MqSendResult Send(IMqSettings mqSettings, string[] msgList); MqSendResult Send(IMqSettings mqSettings, string[] msgList);
} }
} }

View File

@@ -0,0 +1,39 @@
using Microsoft.Extensions.Logging;
using PARR.BLL.Services.Interfaces;
using PARR.GeneratorTemplates.Settings;
namespace PARR.GeneratorTemplates
{
internal class GeneratorTemplate : IGeneratorTemplate
{
private readonly MqSettings mqSettings;
private readonly IMqService mqService;
private readonly ILogger<GeneratorTemplate> logger;
public GeneratorTemplate(
MqSettings mqSettings,
IMqService mqService,
ILogger<GeneratorTemplate> logger
)
{
this.mqSettings = mqSettings;
this.mqService = mqService;
this.logger = logger;
}
public void Start()
{
mqService.InitConsumer(mqSettings);
mqService.Received += (msg) =>
{
logger.LogInformation($"Привет откуда надо!!! ${msg}");
};
}
public void Stop()
{
}
}
}

View File

@@ -1,16 +1,41 @@
using System; using Microsoft.Extensions.Configuration;
using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection;
using System.Linq; using PARR.BLL;
using System.Text; using PARR.DAL;
using System.Threading.Tasks; using PARR.GeneratorTemplates.Settings;
namespace PARR.GeneratorTemplates namespace PARR.GeneratorTemplates
{ {
public static class GeneratorTemplateInstaller public static class GeneratorTemplateInstaller
{ {
//public static void InstallGeneratorTemplateServices(this IServiceCollection services, IConfiguration configuration) //1
//{ public static void InstallGeneratorTemplateServices(this IServiceCollection services, IConfiguration configuration)
{
services.InstallDalServices(configuration);
services.InstallBllServices(configuration);
var mqSettings = new MqSettings();
configuration.GetSection(nameof(MqSettings)).Bind(mqSettings);
services.AddSingleton(mqSettings);
//add other services
services.AddTransient<IGeneratorTemplate, GeneratorTemplate>();
}
//2
public static IConfigurationBuilder AddGeneratorTemplateConfigurations(this IConfigurationBuilder builder, IServiceCollection services)
{
builder.AddDalConfigurations(services);
return builder;
}
//3
public static void AddGeneratorTemplateSettings(this IServiceCollection services, IConfiguration configuration)
{
services.AddDallSettings(configuration);
}
//}
} }
} }

View File

@@ -0,0 +1,8 @@
namespace PARR.GeneratorTemplates
{
public interface IGeneratorTemplate
{
void Start();
void Stop();
}
}

View File

@@ -6,4 +6,9 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PARR.BLL\PARR.BLL.csproj" />
<ProjectReference Include="..\PARR.DAL\PARR.DAL.csproj" />
</ItemGroup>
</Project> </Project>

View File

@@ -0,0 +1,12 @@
using PARR.BLL.Contracts.Interfaces;
namespace PARR.GeneratorTemplates.Settings
{
internal class MqSettings : IMqSettings
{
public string HostName { get; set; } = string.Empty;
public string QueueName { get; set; } = string.Empty;
public string User { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
}

View File

@@ -15,4 +15,8 @@
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PARR.GeneratorTemplates\PARR.GeneratorTemplates.csproj" />
</ItemGroup>
</Project> </Project>

View File

@@ -1,9 +1,26 @@
using PARR.GeneratorTemplates;
using PARR.GeneratorTemplatesWorker; using PARR.GeneratorTemplatesWorker;
using Serilog; using Serilog;
IHost host = Host.CreateDefaultBuilder(args) IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services => .ConfigureServices((hostContext, services) =>
{ {
services.InstallGeneratorTemplateServices(hostContext.Configuration);
//hostContext.Configuration.AddGeneratorTemplateConfigurations(services);
//services.AddGeneratorTemplateSettings(hostContext.Configuration);
//services.AddHostedService<Worker>();
})
//.ConfigureAppConfiguration((hostContext, configBuilder) =>
//{
//TODO: !!! !!! !!! не смог прикрутить AddGeneratorTemplateConfigurations, не могу прокинуть туда сервисы
// configBuilder.AddGeneratorTemplateConfigurations(hostContext.Services);
//})
.ConfigureServices((hostContext, services) =>
{
//services.AddGeneratorTemplateSettings(hostContext.Configuration);
services.AddHostedService<Worker>(); services.AddHostedService<Worker>();
}) })
.UseSerilog((hostContext, services, config) => .UseSerilog((hostContext, services, config) =>

View File

@@ -1,21 +1,34 @@
using PARR.GeneratorTemplates;
namespace PARR.GeneratorTemplatesWorker namespace PARR.GeneratorTemplatesWorker
{ {
public class Worker : BackgroundService public class Worker : BackgroundService
{ {
private readonly ILogger<Worker> _logger; private readonly ILogger<Worker> _logger;
private readonly IGeneratorTemplate generatorTemplate;
public Worker(ILogger<Worker> logger) public Worker(ILogger<Worker> logger, IGeneratorTemplate generatorTemplate)
{ {
_logger = logger; _logger = logger;
this.generatorTemplate = generatorTemplate;
} }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{ {
while (!stoppingToken.IsCancellationRequested) // todo: обернуть в таск?
generatorTemplate.Start();
//while (!stoppingToken.IsCancellationRequested)
//{
// _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
// await Task.Delay(1000, stoppingToken);
//}
}
public override Task StopAsync(CancellationToken cancellationToken)
{ {
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); generatorTemplate.Stop();
await Task.Delay(1000, stoppingToken);
} return base.StopAsync(cancellationToken);
} }
} }
} }

View File

@@ -4,5 +4,8 @@
"Default": "Information", "Default": "Information",
"Microsoft.Hosting.Lifetime": "Information" "Microsoft.Hosting.Lifetime": "Information"
} }
},
"MqSettings": {
"HostName": "10.99.253.216"
} }
} }

View File

@@ -22,5 +22,11 @@
} }
} }
] ]
},
"MqSettings": {
"HostName": "parr-rabbitmq",
"QueueName": "parr-generate-templates",
"User": "generate_templates_worker",
"Password": "Dhgdf%d&609sssa"
} }
} }