问题
I am trying to read new messages from RabbitMQ using a Windows service but the event of receiving new messages doesn't fire. This service could be launched as a Console Application in Debug Mode. In this case the event fires and I can read new messages. The service is launched with the user I use to log into Windows. This is a part of code in the OnStart service event handler
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");
Why doesn't the windows service receive messages whereas when it is launched as Console application in Debug Mode it does receive messages?
回答1:
When you're working with windows services you have to change your code a bit. your code will work fine within a console mode app but not a windows service, your Connection, Channel and Consumer objects must be declared globally as class private members something like this:
private static ConnectionFactory _factory;
private static IConnection _connection;
private static IModel _channel;
private static EventingBasicConsumer _consumer;
Then OnStart method you can create your Connection and Channel objects i.e
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);
}
Finally don't forget to dispose and close the connection and the channel upon the windows service stopping.
protected override void OnStop()
{
_channel.Close();
_connection.Close();
_channel.Dispose();
_connection.Dispose();
}
回答2:
Check the user running the service (Log on As) if it has the right permissions to run what you have in the service
来源:https://stackoverflow.com/questions/43879901/access-to-new-rabbitmq-messages-from-windows-service