RabbitMQ消费者作为Windows服务

时间:2015-11-13 22:08:41

标签: .net windows-services rabbitmq mongodb-.net-driver

我有一个rabbitmq消费者应用程序在.net中实现"发布/订阅模式,它完美地作为控制台应用程序运行但是当我将其部署为Windows服务时,它似乎并没有将数据保存到mongodb中。

    protected override void OnStart(string[] args)
    {
        try
        {
             var connectionString = "mongodb://localhost";
            var client = new MongoClient(connectionString);
            var factory = new ConnectionFactory() { HostName = "localhost" };            
            using (var connection = factory.CreateConnection())
            {
                using (var channel = connection.CreateModel())
                {
                    channel.ExchangeDeclare(exchange: "test", type: "fanout");
                    var queueName = channel.QueueDeclare().QueueName;
                    channel.QueueBind(queue: queueName,                                       exchange: "logs", routingKey: "");

                    var consumer = new EventingBasicConsumer(channel);
                    consumer.Received += (model, ea) =>
                    {
                        var body = ea.Body;
                        var message = Encoding.UTF8.GetString(body);
                        BsonDocument document = BsonDocument.Parse(message);
                        var database = client.GetDatabase("test");
                        var collection = database.GetCollection<BsonDocument>("test_collection");
                        collection.InsertOneAsync(document);
                    };
                    channel.BasicConsume(queue: queueName,                                       noAck: true,consumer: consumer);

                }
            }
        }
        catch (Exception ex)
        {
            throw;
        }
    }

我有什么遗失的东西吗?

4 个答案:

答案 0 :(得分:8)

在OnStart()中忙碌等待是一个坏主意,因为操作系统将期待从它返回。请在此处阅读:https://msdn.microsoft.com/en-us/library/zt39148a%28v=vs.110%29.aspx

编辑:上面代码的问题在于你在using语句中有你的连接和通道。这样做的关键是将它们置于范围之外。因此,在这种情况下,即使您正在添加事件处理程序,也可以在退出范围和处理通道后不久等。要解决此问题,请将连接,通道和使用者拉出`的OnStart&#39;方法,并使他们成为类(可能是私人)成员。即使退出方法并且你的事件应该继续倾听,这应该保持打开状态。

答案 1 :(得分:0)

对我的Onstart方法进行以下更改可以解决问题

    protected override void OnStart(string[] args)
    {

        ConnectionFactory factory = new ConnectionFactory { HostName = localhost" };
        var connectionString = "mongodb://localhost";
        var client = new MongoClient(connectionString);


        using (IConnection connection = factory.CreateConnection())
        {
            using (IModel channel = connection.CreateModel())
            {
                channel.ExchangeDeclare(exchange: "test", type: "fanout");

                string queueName = channel.QueueDeclare();

                channel.QueueBind(queueName, "test", "");

                this.EventLog.WriteEntry("Waiting for messages");

                QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel);
                channel.BasicConsume(queueName, true, consumer);

                while (true)
                {
                    BasicDeliverEventArgs e = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
                    var message = Encoding.UTF8.GetString(e.Body);
                    BsonDocument document = BsonDocument.Parse(message);
                    var database = client.GetDatabase("test");
                    var collection = database.GetCollection<BsonDocument>("test_collection");
                    collection.InsertOneAsync(document);

                }
            }
        }
    }

答案 2 :(得分:0)

今天,我们需要将RabbitMQ消费者用作Windows服务,并使用OnStart方法中的Timer进行解决。

private Timer _timer;

protected override void OnStart(string[] args)

{
     _timer = new Timer();
     _timer.Interval = 5000; 
     _timer.Elapsed += new ElapsedEventHandler(this.OnTimer);
     _timer.Start();
}

public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
     _timer.Enabled = false;

     ...
}

非常感谢您的帮助,也希望也能为该解决方案提供帮助

答案 3 :(得分:0)

以下答案可帮助我解决此问题。如上所述,您不应在OnStart方法中使用不返回的 using语句。这样您就可以在OnStart方法中获得一条消息,但无法通过using语句来声明使用者。

the solution which fixes the problem for me

我希望这对您也有帮助