我试图将我的RabbitMQ微服务转换为Windows服务。我已经使用TopShelf进行转换。我的RabbitMQ微服务完全可以自行完成,但是当我将它作为服务运行时,它不再接收消息。在我public static void Main(string[] args)
我:当TopShelf作为Windows服务使用时,RabbitMQ未收到消息
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();
}
在A similar SO question它看起来像它寻找有事与Windows服务是想要返回,但我不知道如何致电ConsumeMessage
所以consumer.Received += (model, ea) => {...};
被执行。
编辑:它看起来像我的拦截机制Console.ReadLine();
被服务忽略,所以它只是继续和处置的消费者。那么我该如何阻止消息被接收呢?
因为我使用Topshelf,所以我有'tc => tc.Start();'如上所述,我认为它与'OnStart'相同?所以如果我正确理解你,1.建立连接,通道和消费者类成员,2.在Start()中初始化,然后在'ConsumeMessage'中保留'consumer.Received + =(model,ea)=> {...这是怎么回事?什么是阻止'ConsumeMessage'完成并将'consumer.Received + =(model,ea)=> {...}'超出范围? – DevEng
是的,你的问题真的在'using'语句中 - 你的代码在Console.ReadLine()之前传递了它的大括号,并且你的通道没有任何消息 –
所以我让类成员private IConnection连接;私人EventingBasicConsumer消费者;私人IModel频道;'将初始化移动到'Start()'并移除'使用(var channel = connection.CreateModel()){'当我将它作为命令行应用执行时,我的结果会返回,但如果我将它作为服务运行,返回404,所以它在某种程度上解决了问题,让我明天再试一次,看看我是否可以修复它并接受你的回答 – DevEng