【问题标题】:Access to new RabbitMQ messages from windows service从 Windows 服务访问新的 RabbitMQ 消息
【发布时间】:2017-05-09 21:08:02
【问题描述】:

我正在尝试使用 Windows 服务从 RabbitMQ 读取新消息,但没有触发接收新消息的事件。该服务可以作为调试模式下的控制台应用程序启动。在这种情况下,事件触发,我可以阅读新消息。 该服务由我用来登录 Windows 的用户启动。 这是 OnStart 服务事件处理程序中的一部分代码

var factory = new ConnectionFactory() { HostName = "localhost" };
                using (var conn = factory.CreateConnection())
                {
                    using (var channel = conn.CreateModel())
                    {
                        channel.ExchangeDeclare("sm_posts", "fanout");
                        var argu = new Dictionary<string, object>();
                        argu.Add("x-max-length", 10000);

                        var consumerQueue = channel.QueueDeclare().QueueName;
                        channel.QueueBind(queue: consumerQueue, exchange: "sm_posts", routingKey: "");
                        var consumer = new EventingBasicConsumer(channel);

                        log.Info("Waiting for new messages...");

                        consumer.Received += (model, ea) =>
                        {
                            count++;
                            var body = ea.Body;
                            var message = Encoding.UTF8.GetString(body);

                            log.Info(message + "\n\n\n\n\n");

为什么 windows 服务不接收消息,而在调试模式下作为控制台应用程序启动时却接收消息?

【问题讨论】:

  • 将用户帐户更改为网络服务之一或创建一个具有管理员权限的帐户,可以从队列中读取。
  • @t0mm13b 感谢您的回复。如果我尝试使用网络服务启动服务,则会出现错误。如何创建一个可以从队列中读取的帐户?
  • 查看 rabbitmq 日志文件 - 在您启动服务时是否有连接尝试?
  • @Alex Buyny 我从 C:\Users\Administrator\AppData\Roaming\RabbitMQ\log 文件夹中删除了日志。重新启动了服务。并且日志目录仍然是空的。我还在我的 Windows 服务程序日志中看到调用了该方法(其中声明了队列并绑定到交换)

标签: c# windows-services rabbitmq


【解决方案1】:

当您使用 Windows 服务时,您必须稍微更改您的代码。您的代码可以在控制台模式应用程序中正常工作,但不能在 Windows 服务中正常工作,您的 Connection、Channel 和 Consumer 对象必须在全局范围内声明为类私有成员,如下所示:

private static ConnectionFactory _factory;
private static IConnection _connection;
private static IModel _channel;
private static EventingBasicConsumer _consumer;

然后 OnStart 方法你可以创建你的 Connection 和 Channel 对象,即

    protected override void OnStart(string[] args)
            {
                _factory = new ConnectionFactory()
                {
                    HostName = "Host",
                    UserName = "username",
                    Password = "password"
                };
                _connection = _factory.CreateConnection();
                _channel = _connection.CreateModel();

                _channel.QueueDeclare(queue: _queueName, durable: false, exclusive: false,autoDelete: false, arguments: null);

                _consumer = new EventingBasicConsumer(_channel);

                _consumer.Received += (s, ev) =>
                {
                    //Handle messages here.
                };

                _channel.BasicConsume(queue: _queueName, autoAck: true, consumer: _consumer);
            }

最后别忘了在windows服务停止的时候配置和关闭连接和通道。

 protected override void OnStop()
        {
            _channel.Close();
            _connection.Close();
            _channel.Dispose();
            _connection.Dispose();
        }

【讨论】:

    【解决方案2】:

    检查运行服务的用户(登录身份)是否有权运行您在服务中拥有的内容

    【讨论】:

      猜你喜欢
      • 2014-06-01
      • 1970-01-01
      • 2015-06-21
      • 1970-01-01
      • 2018-08-01
      • 2016-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多