web-dev-qa-db-ja.com

ASP.NET CoreアプリケーションでRabbitMQコンシューマーをセットアップする

RabbitMQメッセージを消費したいASP.NET Coreアプリケーションがあります。

コマンドラインアプリケーションでパブリッシャーとコンシューマーを正常にセットアップしましたが、Webアプリケーションで適切にセットアップする方法がわかりません。

Startup.csで初期化することを考えていましたが、もちろん起動が完了すると死にます。

Webアプリから消費者を正しい方法で初期化する方法は?

21
severin

コンシューマー/リスナーのシングルトンパターンを使用して、アプリケーションの実行中にそれを保持します。 IApplicationLifetimeインターフェイスを使用して、アプリケーションの起動/停止時にコンシューマを起動/停止します。

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<RabbitListener>();
    }


    public void Configure(IApplicationBuilder app)
    {
        app.UseRabbitListener();
    }
}

public static class ApplicationBuilderExtentions
{
    //the simplest way to store a single long-living object, just for example.
    private static RabbitListener _listener { get; set; }

    public static IApplicationBuilder UseRabbitListener(this IApplicationBuilder app)
    {
        _listener = app.ApplicationServices.GetService<RabbitListener>();

        var lifetime = app.ApplicationServices.GetService<IApplicationLifetime>();

        lifetime.ApplicationStarted.Register(OnStarted);

        //press Ctrl+C to reproduce if your app runs in Kestrel as a console app
        lifetime.ApplicationStopping.Register(OnStopping);

        return app;
    }

    private static void OnStarted()
    {
        _listener.Register();
    }

    private static void OnStopping()
    {
        _listener.Deregister();    
    }
}
  • アプリがホストされている場所に注意する必要があります。たとえば、IISは、コードのリサイクルと停止を実行できます。
  • このパターンは、リスナーのプールに拡張できます。
26
Ilya Chumakov

これは私のリスナーです:

public class RabbitListener
{
    ConnectionFactory factory { get; set; }
    IConnection connection { get; set; }
    IModel channel { get; set; }

    public void Register()
    {
        channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null);

        var consumer = new EventingBasicConsumer(channel);
        consumer.Received += (model, ea) =>
        {
            var body = ea.Body;
            var message = Encoding.UTF8.GetString(body);
            int m = 0;
        };
        channel.BasicConsume(queue: "hello", autoAck: true, consumer: consumer);
    }

    public void Deregister()
    {
        this.connection.Close();
    }

    public RabbitListener()
    {
        this.factory = new ConnectionFactory() { HostName = "localhost" };
        this.connection = factory.CreateConnection();
        this.channel = connection.CreateModel();


    }
}
7
Pàldi Gergő