简体   繁体   English

RabbitMQ C# 实践示例

[英]RabbitMQ C# Practical Example

I am new to RabbitMQ and am having trouble finding a VS2017 C# example that does more that prints to the Console.我是 RabbitMQ 的新手,并且无法找到一个 VS2017 C# 示例,该示例执行更多打印到控制台的操作。 I can send and receive messages no problem, but I would like to take the contents of the message and actually use it.我可以发送和接收消息没问题,但我想获取消息的内容并实际使用它。 Below is the code I have:下面是我的代码:

using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.IO;

namespace MyCode
{
  class Program
  {
    public static void Main()
    {
      var factory = new ConnectionFactory() { HostName = "xxx.xx.x.x", UserName = "MyTest", Password = "MyTest", Port = 5672 };
      using (var connection = factory.CreateConnection())
      {
        using (var channel = connection.CreateModel())
        {

          channel.QueueDeclare(queue: "MyTest", durable: false, exclusive: false, autoDelete: false, arguments: null);

          var consumer = new EventingBasicConsumer(channel);
          consumer.Received += (model, ea) =>
          {
            var body = ea.Body;
            var message = Encoding.UTF8.GetString(body);
            DoSomething(message);
          };

          channel.BasicConsume(queue: "MyTest", autoAck: true, consumer: consumer);
        }
      }
    }
    static void DoSomething(string message)
    {
      File.AppendAllText(@"C:\RMQ.txt", message);
    }
  }
}

The problem is, I can't ever seem to get anything out of the Consumer.Received step.问题是,我似乎无法从 Consumer.Received 步骤中得到任何东西。 Any help would be much appreciated!任何帮助将非常感激!

EDIT::编辑::

I was able to make it work by using this code instead:我能够通过使用此代码来使其工作:

  var factory = new ConnectionFactory() { HostName = "xxx.xx.x.x", UserName = "MyTest", Password = "MyTest", Port = 5672 };
  using (IConnection connection = factory.CreateConnection())
  {
    using (IModel channel = connection.CreateModel())
    {

      channel.QueueDeclare(queue: "MyTest", durable: false, exclusive: false, autoDelete: false, arguments: null);

      BasicGetResult consumer = channel.BasicGet("MyTest", true);

      if (consumer != null)
      {
        string message = Encoding.UTF8.GetString(consumer.Body);
        DoSomething(message);
      }

    }
  }

Anybody see any issues with this?有人看到这有什么问题吗?

The problem with your first piece of code is that your program finishes execution before it can handle any messages.你的第一段代码的问题是你的程序在它可以处理任何消息之前就完成了执行。 EventingBasedConsumer is asynchronous and won't actually prevent you program from exiting. EventingBasedConsumer是异步的,实际上不会阻止您的程序退出。 You need to implement a wait of some sort to be able to actually handle messages.您需要实现某种等待才能实际处理消息。 Try adding Thread.Sleep(10000);尝试添加Thread.Sleep(10000); just after Channel.BasicConsume and check if there are any messages being processed.就在Channel.BasicConsume之后,检查是否有正在处理的消息。

For fire and forget applications, that tries to setup the read, try not to use the "using" statement for your connection and channel.对于尝试设置读取的即发即弃应用程序,尽量不要对您的连接和通道使用“using”语句。 They will go out of scope (set for garbage collection) once the the subroutine finish the execution.一旦子例程完成执行,它们将超出范围(设置为垃圾收集)。

Obviously, you need to have the console application up and running to receive the message.显然,您需要启动并运行控制台应用程序才能接收消息。 So, I did put a Console.Readline() in the calling app to prevent the thread from exiting.所以,我确实在调用应用程序中放置了一个 Console.Readline() 以防止线程退出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM