我正在尝试将我的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
方法处理它们。