2013-07-22 55 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