2017-08-14 47 views
1

我试图将我的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();被服务忽略,所以它只是继续和处置的消费者。那么我该如何阻止消息被接收呢?

回答

0

您的代码使用using结构,这意味着当您的OnStart方法返回时,您的channel将实际处置。该docs建议做OnStart你的初始化,所以创建channelconsumer存在,但不使用using

this.connection = factory.CreateConnection(); 

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

那么这些对象将继续存在OnStart方法完成之后。您应该在OnStop方法中处理它们。

+0

因为我使用Topshelf,所以我有'tc => tc.Start();'如上所述,我认为它与'OnStart'相同?所以如果我正确理解你,1.建立连接,通道和消费者类成员,2.在Start()中初始化,然后在'ConsumeMessage'中保留'consumer.Received + =(model,ea)=> {...这是怎么回事?什么是阻止'ConsumeMessage'完成并将'consumer.Received + =(model,ea)=> {...}'超出范围? – DevEng

+0

是的,你的问题真的在'using'语句中 - 你的代码在Console.ReadLine()之前传递了它的大括号,并且你的通道没有任何消息 –

+0

所以我让类成员private IConnection连接;私人EventingBasicConsumer消费者;私人IModel频道;'将初始化移动到'Start()'并移除'使用(var channel = connection.CreateModel()){'当我将它作为命令行应用执行时,我的结果会返回,但如果我将它作为服务运行,返回404,所以它在某种程度上解决了问题,让我明天再试一次,看看我是否可以修复它并接受你的回答 – DevEng

相关问题