我的理解是IModel
个实例创建起来相当便宜,这就是我的开始。我正在为每个使用它的类创建一个单独的IModel
:每个Application Service类都有自己的IModel
,每个Controller
也是如此。它工作正常,但打开30多个频道有点令人担忧。
我考虑过序列化对共享IModel
的访问权限:
lock(publisherLock)
publisherModel.BasicPublish(...);
但是现在没有充分理由争论。
那么,从ASP.NET MVC应用程序发布消息到RabbitMQ交换中的正确方法是什么?
答案 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