我正在尝试使用消息队列(RabbitMQ)在基于微服务的架构中处理请求授权。
我已经按照这些说明将接收器和发送器配置为 .NET Core 中的控制台应用程序。但是,当在现实世界的示例中使用它时,我的应用程序接收项目不会作为消费者收集消息。
我假设我必须在 中注册消费者Startup.cs,但我似乎无法让它工作。
我的消费者/响应者代码:
public class RabbitMqHandler
{
private readonly IJWTFactory _jwtFactory;
public RabbitMqHandler(IJWTFactory jWTFactory)
{
_jwtFactory = jWTFactory;
}
public void Register()
{
var mqFactory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = mqFactory.CreateConnection())
{
Console.WriteLine("Listening on Rabbit MQ");
using (var channel = connection.CreateModel())
{
channel.QueueDeclare(queue: "Authorize", durable: false, exclusive: false, autoDelete: false, arguments: null);
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var jwtToken = Encoding.UTF8.GetString(body);
Console.WriteLine("Rceived Message");
var validatedToken = _jwtFactory.ValidateTokenSignature(jwtToken);
SendResponse(validatedToken);
};
channel.BasicConsume(queue: "Authorize", autoAck: true, consumer: consumer);
}
}
}
public void Deregister()
{
}
Run Code Online (Sandbox Code Playgroud)
Startup.cs注册 .AddSingleton()
编辑:我添加了一些额外的监听代码,这肯定在启动时运行,但 RabbitMQ 没有将应用程序显示为消费者或通道:
public static class ApplicationBuilderExtentions
{
public static RabbitMqHandler Listener { get; set; }
public static IApplicationBuilder UseRabbitListener(this IApplicationBuilder app)
{
Listener = app.ApplicationServices.GetService<RabbitMqHandler>();
var life = app.ApplicationServices.GetService<IApplicationLifetime>();
life.ApplicationStarted.Register(OnStarted);
//press Ctrl+C to reproduce if your app runs in Kestrel as a console app
life.ApplicationStopping.Register(OnStopping);
return app;
}
private static void OnStarted()
{
Listener.Register();
}
private static void OnStopping()
{
Listener.Deregister();
}
}
Run Code Online (Sandbox Code Playgroud)
总结一下:
@Evk提供的答案(在评论中):
"
using旨在处理事物,Dispose当您到达块的末尾时它会调用using。BasicConsume不是阻塞调用,因此它开始消耗并立即返回。
紧接着using通道和连接都到达块的末尾,处理它们(处理它们与关闭相同)。”
我想添加以下内容:如果删除 using 可以很容易地带来所需的结果,您可以快速尝试。更改以下代码行:
using (var connection = mqFactory.CreateConnection())
Run Code Online (Sandbox Code Playgroud)
到:
var connection = mqFactory.CreateConnection();
Run Code Online (Sandbox Code Playgroud)
这将立即发挥作用。但请注意,它也消除了正确的处置 - 所以你需要补充一点 -这是 Microsoft 的一篇文章,描述了如何IDisposable正确实施。