11、Send Receive 发送接收
Publish/Subsrcibe和Request/Response模式是位置透明的,在这两个模式中,你不需要去指定消息的消费者具体所处的位置。但Send/Receive模式是专门为通过指定队列名进行通信而设计的。它不限制什么样的消息类型才能发送到这个队列。这意味着,你能够发送不同类型的消息到同一个队列中。
Send/Receive模式是创建“命令管道”的理想方法,“命令管道”就是那种你想为单个命令处理程序建立一个缓冲通道的场景。
要发送一个消息,可以使用IBus的Send方法,指定要发送消息的队列名称和消息:
bus.Send("my.queue", new MyMessage{ Text = "hello widget!"});
为特定消息类型创建一个消息接收器,要使用IBus上的Receive方法:
bus.Receive<MyMessage>("my.queue", message => Console.WriteLine("Message:{0}",message.Text));
你能够在同一队列上为不同的消息类型分别创建接收者,即通过使用Receive 带有一个Action的重载方法,代码如下:
bus.Receive("my.queue", x => x .Add<MyMessage>(message => deliveredMyMessage = message) .Add<MyOtherMessage>(message => deliveredMyOtherMessage = message));//多个接收者
如果消息送达了一个接收队列,但是没有匹配到任何接收者,EasyNetQ会把消息附带一个异常“No handler for message type写到EasyNetQ的错误队列”。
注意:如果对同一队列多次调用bus.Receive方法(指定队列名一样),会创建新的消费者去消费该队列,并让RabbitMQ轮转顺序发送这些消息。
假如你正在消费不同类型的消息,却用不同的bus.Receive调用(因此也是不同的消费者),你的一些消息将会出现在错误队列中,因为EasyNetQ不会为你的消息类型找到处理程序,处理程序必须与它的消费者相关联。如下:
bus.Receive<MyMessage>("my.queue", message => Console.WriteLine("MyMessage: {0}", message.Text)); bus.Receive<MyOtherMessage>("my.queue", message => Console.WriteLine("MyOtherMessage: {0}", message.Text));
简单说,假如你想在一个队列上消费不同类型的消息,你应该用 ”带有一个Action的重载的Receive方法”。而不应该用上面两行代码(那会产生错误)