RabbitMQ:从ASP.NET MVC应用程序发布

时间:2013-07-22 13:40:50

标签: asp.net-mvc rabbitmq

我的理解是IModel个实例创建起来相当便宜,这就是我的开始。我正在为每个使用它的类创建一个单独的IModel:每个Application Service类都有自己的IModel,每个Controller也是如此。它工作正常,但打开30多个频道有点令人担忧。

我考虑过序列化对共享IModel的访问权限:

lock(publisherLock)
    publisherModel.BasicPublish(...);

但是现在没有充分理由争论。

那么,从ASP.NET MVC应用程序发布消息到RabbitMQ交换中的正确方法是什么?

2 个答案:

答案 0 :(得分:3)

您不能做的是允许多个线程使用某个频道,因此在多个请求中保持频道开放是一个坏主意。

IModel实例创建起来很便宜,但不是免费的,因此您可以采取以下几种方法:

最安全的做法是每次想要发布并立即再次关闭它时创建一个频道。像这样:

using(var model = connection.CreateModel())
{
    var properties = model.CreateBasicProperties();
    model.BasicPublish(exchange, routingKey, properties, msg);
}

您可以在应用程序的生命周期内保持连接处于打开状态,但请务必检测是否断开了连接并且有代码重新连接。

这种方法的缺点是你有为每个发布创建一个频道的开销。

另一种方法是在专用发布线程上保持通道打开,并使用BlockingCollection或类似方法将所有发布调用封送到该线程。这将更有效,但实施起来更复杂。

答案 1 :(得分:0)

这是你可以使用的东西,

BrokerHelper.Publish("Aplan chaplam, chaliye aai mein :P");

及以下是BrokerHelper类的定义。

public static class BrokerHelper
{
    public static string Username = "guest";
    public static string Password = "guest";
    public static string VirtualHost = "/";
    // "localhost" if rabbitMq is installed on the same server,
    // else enter the ip address of the server where it is installed.
    public static string HostName = "localhost";
    public static string ExchangeName = "test-exchange";
    public static string ExchangeTypeVal = ExchangeType.Direct;
    public static string QueueName = "SomeQueue";
    public static bool QueueExclusive = false;
    public static bool QueueDurable = false;
    public static bool QueueDelete = false;
    public static string RoutingKey = "yasser";

    public static IConnection Connection;
    public static IModel Channel;
    public static void Connect()
    {
        var factory = new ConnectionFactory();
        factory.UserName = Username;
        factory.Password = Password;
        factory.VirtualHost = VirtualHost;
        factory.Protocol = Protocols.FromEnvironment();
        factory.HostName = HostName;
        factory.Port = AmqpTcpEndpoint.UseDefaultPort;
        Connection = factory.CreateConnection();
        Channel = Connection.CreateModel();
    }

    public static void Disconnect()
    {
        Connection.Close(200, "Goodbye");
    }

    public static bool IsBrokerDisconnected()
    {
        if(Connection == null) return true;
        if(Connection.IsOpen) return false;
        return true;
    }

    public static void Publish(string message)
    {
        if (IsBrokerDisconnected()) Connect();

        Channel.ExchangeDeclare(ExchangeName, ExchangeTypeVal.ToString());
        Channel.QueueDeclare(QueueName, QueueDurable, QueueExclusive, QueueDelete, null);
        Channel.QueueBind(QueueName, ExchangeName, RoutingKey);
        var encodedMessage = Encoding.ASCII.GetBytes(message);
        Channel.BasicPublish(ExchangeName, RoutingKey, null, encodedMessage);
        Disconnect();
    }
}

进一步阅读:Introduction to RabbitMQ with C# .NET, ASP.NET and ASP.NET MVC with examples