向 .NET Core 注册 RabbitMQ Consumer?

Dan*_*ndy 6 c# rabbitmq

我正在尝试使用消息队列(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)

总结一下:

  • 如何在 .NET Core 中正确配置消费者来消费消息?
  • 期望消息队列来管理请求/响应风格的通信是错误的吗?
  • 我应该只使用 API 调用来对用户进行身份验证和授权吗?

Mat*_*att 1

@Evk提供的答案(在评论中):

"using旨在处理事物,Dispose当您到达块的末尾时它会调用usingBasicConsume不是阻塞调用,因此它开始消耗并立即返回。
紧接着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正确实施。