【问题标题】:Connecting to RabbitMQ, method level best practices?连接到 RabbitMQ,方法级别的最佳实践?
【发布时间】:2011-07-13 17:00:13
【问题描述】:

我有一个使用rabbitmq 读写消息的类。我不想在此类的构造函数中或在读写方法中包含连接相关信息。相反,我想在使用 write 和 read 方法时建立连接。解决此问题的最佳方法/做法是什么?

//编辑1

public class Rabbit : IMessageBus
{   
    // Implementation of methods for Rabbit class go here
    private List<string> publishQ = new List<string>();
    private List<string> subscribeQ = new List<string>();

    ConnectionFactory factory = null;
    IConnection connection = null;
    IModel channel = null;  
    QueueingBasicConsumer consumer = null;  


    public void write ( Measurement m1 )
    {
        byte[] body = Measurement.AltSerialize( m1 );

        foreach (string queue in publishQ) 
        {
            channel.BasicPublish("", queue, null, body);
            Console.WriteLine("\n  [x] Sent to queue {0}.", queue);
        }
    }

    public void publish(string queueName)
    {   
        channel.QueueDeclare(queueName, true, false, false, null); //durable=true

        publishQ.Add(queueName); //and, add it the list of queue names to publish to
    }

    public Measurement read() 
    {       
        foreach (string queue in subscribeQ) 
        {
            channel.BasicConsume(queue, true, consumer);
        }

        System.Console.WriteLine(" [*] Waiting for messages." +
                                "To exit press CTRL+C");
        BasicDeliverEventArgs ea = 
            (BasicDeliverEventArgs)consumer.Queue.Dequeue();

        return Measurement.AltDeSerialize(ea.Body);
    }

    public void subscribe(string queueName)
    {
        channel.QueueDeclare(queueName, true, false, false, null);
        subscribeQ.Add(queueName);
    }

    public static string MsgSysName;
    public string MsgSys
    {
        get 
        { 
            return MsgSysName;
        }
        set
        {
            MsgSysName = value;
        }
    }

    public Rabbit(string _msgSys) //Constructor
    {   
        factory = new ConnectionFactory();
        factory.HostName = "localhost"; 
        connection = factory.CreateConnection();
        channel = connection.CreateModel();
        consumer = new QueueingBasicConsumer(channel);

        System.Console.WriteLine("\nMsgSys: RabbitMQ");
        MsgSys = _msgSys;
    }

    ~Rabbit()
    {
        //
    }   
}

【问题讨论】:

  • 仅供参考,您正在到处泄漏资源。其中几个类是 IDisposable。终结器是邪恶的 - 摆脱那个空的!

标签: c# methods rabbitmq amqp


【解决方案1】:

您是否考虑过将Func&lt;Connection&gt; 传递给构造函数?换句话说,一种您可以在需要时获得连接的方式

(显然您需要在某处中传递连接信息,除非您要静态访问它...不寒而栗。)

编辑:好的,我不熟悉 RabbitMQ,但假设它有某种实现 IDisposableConnection 类,它看起来像这样:

public class MessageHandler
{
    private readonly Func<Connection> connectionProvider;

    public MessageHander(Func<Connection> connectionProvider)
    {
        this.connectionProvider = connectionProvider;
    }

    public void WriteMessage(string message)
    {
        using (Connection connection = connectionProvider.Invoke())
        {
            connection.DoSomething(message);
        }
    }
}

然后用类似的东西创建它:

MessageHandler handler = new MessageHandler(() => new Connection(server));

现在,如果涉及到更多“有趣”的内容,您可能需要编写一个单独的 ConnectionProvider 类。当然,RabbitMQ 可能有一些示例代码 - 你应该先查阅它和他们的文档,因为我真的不知道我在说什么 :)

【讨论】:

  • 不,但这听起来是个好主意。我怎么做?请给我一个简单的例子吗?
  • 我也编辑了我的问题。它现在有我正在学习的课程。但是,您不是还在初始化构造函数吗(因此整个类都使用该连接?)
  • @Demi:不,它向构造函数传递了一种获取连接的方法。在您要求之前,它不会创建连接。 (您应该查看以下 .NET 命名约定,顺便说一句...)
猜你喜欢
  • 2018-03-21
  • 2011-03-19
  • 1970-01-01
  • 2020-09-18
  • 1970-01-01
  • 2014-10-22
  • 2015-03-25
  • 2015-08-03
相关资源
最近更新 更多