RabbitMQ 在与 TopShelf 作为 Windows 服务一起使用时不接收消息



我正在尝试将我的RabbitMQ微服务转换为Windows服务。 我已经使用TopShelf 进行转换。 我的 RabbitMQ 微服务本身运行得很好,但是当我将其作为服务运行时,它不再接收消息。 在我的public static void Main(string[] args)中,我有:

HostFactory.Run(host =>
{
host.Service<PersonService>(s =>                      
{
s.ConstructUsing(name => new PersonService());
s.WhenStarted(tc => tc.Start());             
s.WhenStopped(tc => tc.Stop());               
});
host.SetDescription("Windows service that provides database access totables."); 
host.SetDisplayName("Service");                   
host.SetServiceName("Service");
});
}

然后在我PersonService课上我有

public void Start() {
ConsumeMessage();
}

最后是我的ConsumeMessage函数:

private static void ConsumeMessage() {
MessagingConfig.SetInstance(new MessagingConstants());
IMessageFactory pmfInst = MessageFactory.Instance;
//message worker
var factory = new ConnectionFactory() {
HostName = MessagingConfig.Instance.GetBrokerHostName(),
UserName = MessagingConfig.Instance.GetBrokerUserName(),
Password = MessagingConfig.Instance.GetBrokerPassword()
};
var connection = factory.CreateConnection();
using (var channel = connection.CreateModel()) {
channel.QueueDeclare(queue: MessagingConfig.Instance.GetServiceQueueName(),
durable: true,
exclusive: false,
autoDelete: false,
arguments: null);
channel.BasicQos(0, 1, false);
var consumer = new EventingBasicConsumer(channel);
channel.BasicConsume(queue: MessagingConfig.Instance.GetServiceQueueName(),
noAck: false,
consumer: consumer);
Console.WriteLine("Service.");
Console.WriteLine(" [x] Awaiting RPC requests");

// Code Below Is Not Executed In Service
consumer.Received += (model, ea) => {
string response = null;
var body = ea.Body;
var props = ea.BasicProperties;
var replyProps = channel.CreateBasicProperties();
replyProps.CorrelationId = props.CorrelationId;
string receivedMessage = null;
try {
receivedMessage = Encoding.UTF8.GetString(body);
response = ProcessMessage(receivedMessage);
}
catch (Exception e) {
// Received message is not valid.
WinLogger.Log.Error(
"Errror Processing Message: " + receivedMessage + " :" + e.Message);
response = "";
}
finally {
var responseBytes = Encoding.UTF8.GetBytes(response);
channel.BasicPublish(exchange: "", routingKey: props.ReplyTo,
basicProperties: replyProps, body: responseBytes);
channel.BasicAck(deliveryTag: ea.DeliveryTag,
multiple: false);
}
};
Console.ReadLine();
}

看着一个类似的SO问题,它看起来与Windows服务想要的返回有关,但我不确定如何调用ConsumeMessage以便执行consumer.Received += (model, ea) => {...};

编辑:看起来我的阻止机制Console.ReadLine();被服务忽略了,所以它只是继续并处理消息消费者。 那么如何阻止那里接收消息呢?

您的代码使用using构造,这意味着当您的OnStart方法返回时,您的channel实际上将被释放。文档建议在OnStart上进行初始化,因此请创建channel并在那里consumer,但不要使用using

this.connection = factory.CreateConnection();
this.channel = connection.CreateModel();
this.consumer = new EventingBasicConsumer(this.channel);

然后OnStart方法完成后,这些对象将继续存在。您应该以OnStop方法处理它们。

最新更新