2013-07-22 53 views
1

我的理解是IModel实例创建起来相当便宜,这就是我开始使用的。我为每个使用它的类别创建了一个单独的IModel:每个应用程序服务类别都有自己的IModel,每个Controller也是如此。它工作正常,但有30多个频道打开有点令人担忧。RabbitMQ:从ASP.NET MVC应用程序发布

我想过序列化到一个共享IModel访问:

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

但现在有争论的毫无理由的一个点。

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

回答

3

你不能做的是允许一个通道被多个线程使用,所以保持通道打开多个请求是一个坏主意。

IModel情况下都便宜创造,而不是免费的,所以有几个办法可以采取:

做最安全的做法很简单,就是要发布并关闭它时都创建一个通道再次马上。事情是这样的:

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

可以保持连接打开的应用程序的生命周期,但可以肯定,如果你失去了连接,并具有代码重新检测。

这种方法的不足之处在于,您有为每次发布创建通道的开销。

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

1

这里有一些东西,你可以用,

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