.net core 在ASP.net核心IHostedService中使用RabbitMQ
我面临一个需要帮助的问题。 我正在开发一个后台进程,该进程将侦听rabbitmq服务器中的队列。 如果我在.net核心控制台应用程序中运行它就可以了。然而,我想用一种更优雅的方式来实现它,比如web服务(这给我带来了很多麻烦,因为它在安装时无法工作)或IIS托管的web应用程序。 当我试图在.net核心web应用程序中托管服务(IHostedService)时,我面临一个作用域服务的问题 下面的代码在控制台应用程序中运行良好。如何使其在.net核心web应用程序中作为IHostedService运行。 我应该改变什么。 谢谢你的帮助。 代码:.net core 在ASP.net核心IHostedService中使用RabbitMQ,.net-core,rabbitmq,.net Core,Rabbitmq,我面临一个需要帮助的问题。 我正在开发一个后台进程,该进程将侦听rabbitmq服务器中的队列。 如果我在.net核心控制台应用程序中运行它就可以了。然而,我想用一种更优雅的方式来实现它,比如web服务(这给我带来了很多麻烦,因为它在安装时无法工作)或IIS托管的web应用程序。 当我试图在.net核心web应用程序中托管服务(IHostedService)时,我面临一个作用域服务的问题 下面的代码在控制台应用程序中运行良好。如何使其在.net核心web应用程序中作为IHostedService
使用系统;
使用System.Collections.Generic;
使用系统数据;
使用System.Data.SqlClient;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
使用PaymentProcessor.Models;
使用Microsoft.Extensions.Configuration;
使用Newtonsoft.Json;
使用Newtonsoft.Json.Linq;
使用RabbitMQ.Client;
使用RabbitMQ.Client.Events;
使用Microsoft.EntityFrameworkCore;
命名空间支付处理器
{
公共类付费处理服务:HostedService
{
i配置配置;
私有实体上下文请求上下文;
私有字符串连接字符串;
私有字符串HostName=“”;
私有字符串用户名=”;
私有字符串密码=”;
私有静态int-MaxRetries;
私营IConnectionFactory;
专用i连接;
私人IModel频道;
公共支付处理服务(IConfiguration配置)
{
this.configuration=配置;
this.connectionString=configuration.GetConnectionString(“StagingContext”);
claimsContext=新实体上下文(connectionString);
HostName=this.configuration.GetValue(“设置:主机名”);
UserName=this.configuration.GetValue(“设置:UserName”);
Password=this.configuration.GetValue(“设置:密码”);
MaxRetries=this.configuration.GetValue(“设置:MaxRetries”).ConvertTo();
}
受保护的覆盖异步任务ExecuteAsync(CancellationToken CancellationToken)
{
连接:
工厂=新连接工厂{HostName=HostName,UserName=UserName,Password=Password};
尝试
{
connection=factory.CreateConnection();
channel=connection.CreateModel();
渠道交换声明(“支付处理交换”、“主题”);
channel.QueueDeclare(“付款处理队列”,真、假、假、空);
channel.QueueBind(“支付处理队列”、“支付处理交换”、“处理”);
var queueArgs=新字典
{
{“x-dead-letter-exchange”,“付款处理交换”},
{“x-dead-letter-routing-key”,“处理\u重试”},
{“x-message-ttl”,10000}
};
渠道交换声明(“支付处理交换”、“主题”);
channel.QueueDeclare(“付款\处理\重试\队列”,true、false、false、queueArgs);
channel.QueueBind(“支付\处理\重试\队列”、“支付\处理\交换”、“处理\重试”,null);
渠道交换声明(“支付、处理、交换”、“主题”);
channel.QueueDeclare(“付款\处理\错误\队列”,真、假、假、空);
channel.QueueBind(“支付\处理\错误\队列”、“支付\处理\交换”、“处理\错误”,null);
渠道交换声明(“支付、处理、交换”、“主题”);
channel.QueueDeclare(“支付\集成\队列”,真、假、假、空);
channel.QueueBind(“支付\集成\队列”、“支付\处理\交换”、“集成”,null);
通道.BasicQos(0,1,false);
var消费者=新事件基本消费者(渠道);
消费者.已接收+=(型号,ea)=>
{
var message=ea.Body.DeSerializeText();
尝试
{
var saveBundle=JObject.Parse(消息);
var msg=(动态)((动态)saveBundle).Message;
字符串referenceNo=(字符串)msg.referenceNo;
var参数=新[]
{
新的SqlParameter
{
DbType=DbType.String,
ParameterName=“ReferenceNo”,
Value=referenceNo
}
};
var result=claimsContext.Database.ExecuteSqlCommand(“dbo.paymentreferencessprocesssingle@ReferenceNo”,参数);
IBasicProperties=channel.CreateBasicProperties();
props.Persistent=true;
props.ContentType=“text/plain”;
props.DeliveryMode=2;
channel.BasicPublish(“支付、处理、交换”、“集成”、道具,(新的MessageEnvelope{RetryCounts=0,Message=JObject.FromObject(新的{ReferenceNo=ReferenceNo}))).Serialize();
}
捕获(例外情况除外)
{
MessageEnvelope信封=JsonConvert.DeserializeObject(消息);
if(envelope.RetryCountsusing System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using PaymentProcessor.Models;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using Microsoft.EntityFrameworkCore;
namespace PaymentProcessor
{
public class PaymentProcessingService : HostedService
{
IConfiguration configuration;
private EntitiesContext claimsContext;
private string connectionString;
private string HostName = "";
private string UserName = "";
private string Password = "";
private static int MaxRetries;
private IConnectionFactory factory;
private IConnection connection;
private IModel channel;
public PaymentProcessingService(IConfiguration configuration)
{
this.configuration = configuration;
this.connectionString = configuration.GetConnectionString ("StagingContext");
claimsContext = new EntitiesContext(connectionString);
HostName = this.configuration.GetValue<string>("Settings:HostName");
UserName = this.configuration.GetValue<string>("Settings:UserName");
Password = this.configuration.GetValue<string>("Settings:Password");
MaxRetries = this.configuration.GetValue<string>("Settings:MaxRetries").ConvertTo<int>();
}
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
connect:
factory = new ConnectionFactory { HostName = HostName, UserName = UserName, Password = Password };
try
{
connection = factory.CreateConnection();
channel = connection.CreateModel();
channel.ExchangeDeclare("payment_rocessing_exchange", "topic");
channel.QueueDeclare("payment_processing_queue", true, false, false, null);
channel.QueueBind("payment_processing_queue", "payment_processing_exchange", "processing");
var queueArgs = new Dictionary<string, object>
{
{ "x-dead-letter-exchange", "payment_processing_exchange" },
{"x-dead-letter-routing-key", "processing_retry"},
{ "x-message-ttl", 10000 }
};
channel.ExchangeDeclare("payment_rocessing_exchange", "topic");
channel.QueueDeclare("payment_processing_retry_queue", true, false, false, queueArgs);
channel.QueueBind("payment_processing_retry_queue", "payment_processing_exchange", "processing_retry", null);
channel.ExchangeDeclare("payment_processing_exchange", "topic");
channel.QueueDeclare("payment_processing_error_queue", true, false, false, null);
channel.QueueBind("payment_processing_error_queue", "payment_processing_exchange", "processing_error", null);
channel.ExchangeDeclare("payment_processing_exchange", "topic");
channel.QueueDeclare("payment_integration_queue", true, false, false, null);
channel.QueueBind("payment_integration_queue", "payment_processing_exchange", "integration", null);
channel.BasicQos(0, 1, false);
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var message = ea.Body.DeSerializeText();
try
{
var saveBundle = JObject.Parse(message);
var msg = (dynamic)((dynamic)saveBundle).Message;
string referenceNo = (string)msg.ReferenceNo;
var parameters = new[]
{
new SqlParameter
{
DbType = DbType.String,
ParameterName = "ReferenceNo",
Value =referenceNo
}
};
var result = claimsContext.Database.ExecuteSqlCommand("dbo.PaymentReferencesProcessSingle @ReferenceNo", parameters);
IBasicProperties props = channel.CreateBasicProperties();
props.Persistent = true;
props.ContentType = "text/plain";
props.DeliveryMode = 2;
channel.BasicPublish("payment_processing_exchange", "integration", props, (new MessageEnvelope { RetryCounts = 0, Message = JObject.FromObject(new { ReferenceNo = referenceNo }) }).Serialize());
}
catch (Exception ex)
{
MessageEnvelope envelope = JsonConvert.DeserializeObject<MessageEnvelope>(message);
if (envelope.RetryCounts < MaxRetries)
{
int RetryCounts = envelope.RetryCounts + 1;
MessageEnvelope messageEnvelope = new MessageEnvelope { RetryCounts = RetryCounts, Message = envelope.Message };
var data = messageEnvelope.Serialize();
channel.BasicPublish("payment_processing_exchange", "processing_retry", null, data);
}
else
{
var data = envelope.Serialize();
channel.BasicPublish("payment_processing_exchange", "processing_error", null, data);
}
}
finally
{
channel.BasicAck(ea.DeliveryTag, false);
}
};
channel.BasicConsume(queue: "payment_processing_queue", autoAck: false, consumer: consumer);
}
catch (Exception ex)
{
Thread.Sleep(10000);
goto connect;
}
}
}
}
services.AddScoped<IHostedService, PaymentProcessingService>();
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
namespace Core
{
internal class Program
{
static async Task Main(string[] args)
{
await new HostBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<ServiceRabbitMQ>(); // register our service here
})
.RunConsoleAsync();
}
}
}