Creating a message consumer

A message consumer is a class that consumes one or more message types, specified by theIConsumer<T> interface, where T is the message type.

public class UpdateCustomerConsumer :
IConsumer<UpdateCustomerAddress>
{
public async Task Consume(ConsumeContext<UpdateCustomerAddress> context)
{
await Console.Out.WriteLineAsync($"Updating customer: {context.Message.CustomerId}"); // update the customer address
}
}

When a consumer is subscribed to a receive endpoint, and a message consumed by the consumer is received by the endpoint, an instance of the consumer is created (using a consumer factory, which is covered –> here <–). The message (wrapped in a ConsumeContext) is then delivered to the consumer via the Consume method.

The Consume method is asynchronous, and returns a Task. The task is awaited by MassTransit, during which time the message is unavailable to other receive endpoints. If the consume method completes successfuly (a task status of RanToCompletion), the message is acknowledged and removed from the queue.

Note

If the consumer faults (such as throwing an exception, resulting in a task status of Faulted), or is somehow cancelled (TaskStatus of Canceled), the exception is propagated back up the pipeline where it can ultimately be retried or moved to an error queue.

Connecting a message consumer

For a consumer to receive messages, the consumer must be connected to a receive endpoint. This is done during bus configuration, particularly within the configuration of a receive endpoint.

An example of connecting a consumer to a receive endpoint is shown below.

var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = cfg.Host(new Uri("rabbitmq://localhost/"), h =>
{
h.Username("guest");
h.Password("guest");
}); cfg.ReceiveEndpoint(host, "customer_update_queue", e =>
{
e.Consumer<UpdateCustomerConsumer>();
});
});

The example creates a bus, which connects to the RabbitMQ running on the local machine, using the default username and password (guest/guest). On that bus. a single receive endpoint is created with the name customer_update_queue. The consumer is connected using the simplest method, which accepts a consumer class with a default constructor.

Note

When a consumer is connected to a receive endpoint, the combined set of message types consumed by all of the consumers connected to the same receive endpoint are subscribed to the queue. The subscription method varies by broker, in the case of RabbitMQ exchange bindings are created for the message types to the exchange/queue for the receive endpoint.

These subscriptions are persistent, and remain in place after the process exits. This ensures that messages published or sent that would be delivered to one of the receive endpoint consumers are saved even is the process is terminated. When the process is started, messages waiting in the queue will be delivered to the consumer(s).

The above example connects the consumer using a default constructor consumer factory. There are several other consumer factories supported, as shown below.

var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = ...; cfg.ReceiveEndpoint(host, "customer_update_queue", e =>
{
// an anonymous factory method
e.Consumer(() => new YourConsumer()); // an existing consumer factory for the consumer type
e.Consumer(consumerFactory); // a type-based factory that returns an object (container friendly)
e.Consumer(consumerType, type => container.Resolve(type)); // an anonymous factory method, with some middleware goodness
e.Consumer(() => new YourConsumer(), x =>
{
// add middleware to the consumer pipeline
x.UseLog(ConsoleOut, async context => "Consumer created");
});
});
});

Connecting to an existing bus

Once a bus has been created, the receive endpoints have been created and cannot be modified. The bus itself, however, provides a temporary (auto-delete) queue which can be used to receive messages. To connect a consumer to the bus temporary queue, a series of Connect methods can be used.

Warning

Published messages will not be received by the temporary queue. Because the queue is temporary, when consumers are connected no bindings or subscriptions are created. This makes it very fast for transient consumers, and avoid thrashing the message broker with temporary bindings.

The temporary queue is useful to receive request responses and faults (via the response/fault address header) and routing slip events (via an event subscription in the routing slip).

var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = ...;
}); busControl.Start(); ConnectHandle handle = busControl.ConnectConsumer<FaultConsumer>();
...
handle.Disconnect(); // disconnect the consumer from the bus pipeline

In addition to the `ConnectConsumer` method, methods for each consumer type are also included (`ConnectHandler``ConnectInstance``ConnectSaga`, and `ConnectStateMachineSaga`).

Connecting an existing consumer instance

While using a consumer instance per message is highly suggested, it is possible to connect an existing consumer instance which will be called for every message. The consumer must be thread-safe, as the`Consume` method will be called from multiple threads simultaneously. To connect an existing instance, see the example below.

var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = ...; cfg.ReceiveEndpoint(host, "customer_update_queue", e =>
{
e.Instance(existingConsumer);
});
});

Handling undeliverable messages

If the configuration of an endpoint changes, or if a message is mistakenly sent to an endpoint, it is possible that a message type is received that does not have any connected consumers. If this occurs, the message is moved to a _skipped queue (prefixed by the original queue name). The original message content is retained, and additional headers are added to indicate the host which moved the message.

Handling messages without a consumer

While creating a consumer is the preferred way to consume messages, it is also possible to create a simple message handler. By specifying a method, anonymous method, or lambda method, a message can be consumed on a receive endpoint.

To configure a simple message handler, refer to the example below.

var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = ...; cfg.ReceiveEndpoint(host, "customer_update_queue", e =>
{
e.Handler<UpdateCustomerAddress>(context =>
return Console.Out.WriteLineAsync($"Update customer address received: {context.Message.CustomerId}"));
});
});

In this case, the method is called for each message received. No consumer is created, and no lifecycle management is performed.

Observing messages via IObserver

With the addition of the IObserver interface, the concept of an observer was added to the .NET framework. MassTransit supports the direct connection of observers to receive endpoints.

Note

Unfortunately, observers are not asynchronous. Because of this, it is not possible to play nice with the async support provided by the compiler when using an observer.

An observer is defined using the built-in IObserver<T> interface, as shown below.

public class CustomerAddressUpdatedObserver :
IObserver<ConsumeContext<CustomerAddressUpdated>>
{
public void OnNext(ConsumeContext<CustomerAddressUpdated> context)
{
Console.WriteLine("Customer address was updated: {0}", context.Message.CustomerId);
} public void OnError(Exception error)
{
} public void OnCompleted()
{
}
}

Once created, the observer is connected to the receive endpoint similar to a consumer.

var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = ...; cfg.ReceiveEndpoint(host, "customer_update_queue", e =>
{
e.Observer<CustomerAddressUpdatedObserver>();
});
});

MassTransit_消费者的创建的更多相关文章

  1. MassTransit_契约的创建

    消息契约的命名规范 命令模式:动词+对象 事件模式:对象+动词 不同模式下要求不同的主键 Creating a message contract In MassTransit, a message c ...

  2. springcloud-Netflix创建服务消费者

    目录 springcloud-Netflix创建服务消费者 Ribbon 创建服务消费者-Ribbon方式 ribbon的架构 Feign 创建包和基本项目结构 创建Feign访问服务的接口和访问co ...

  3. 161130、Dubbo+SpringMVC工程创建详解

    Dubbo出现的目的是为了应对现在高并发,高数据量请求的问题.目前的垂直应用架构已经无法满足现在大数据的冲击,SOA就应运而生,而Dubbo在国内使用的还是比较多,稳定性也比较不错. 架构 节点角色说 ...

  4. Linux多线程之同步2 —— 生产者消费者模型

    思路 生产者和消费者(互斥与同步).资源用队列模拟(要上锁,一个时间只能有一个线程操作队列). m个生产者.拿到锁,且产品不满,才能生产.当产品满,则等待,等待消费者唤醒.当产品由空到不空,通知消费者 ...

  5. 翻译:使用 Redux 和 ngrx 创建更佳的 Angular 2

    翻译:使用 Redux 和 ngrx 创建更佳的 Angular 2 原文地址:http://onehungrymind.com/build-better-angular-2-application- ...

  6. nopCommerce 3.9 大波浪系列 之 事件机制(生产者、消费者)

    一.nop事件机制简介 应用场景:客户支付成功后,需要发送短信.邮件告知客户订单支付成功(短信.邮件由不同模块实现) 实现方法: 1.定义支付成功OrderPaidEvent事件. 2.定义短信,邮箱 ...

  7. Springboot+ActiveMQ(ActiveMQ消息持久化,保证JMS的可靠性,消费者幂等性)

    ActiveMQ 持久化设置: 在redis中提供了两种持久化机制:RDB和AOF 两种持久化方式,避免redis宕机以后,能数据恢复,所以持久化的功能 对高可用程序来说 很重要. 同样在Active ...

  8. Kafka技术内幕 读书笔记之(五) 协调者——消费者加入消费组

    消费者客户端轮询的3个步骤:发送拉取请求,客户端轮询,获取拉取结果 . 消费者在发送拉取请求之前,必须首先满足下面的两个条件.- 确保消费者已经连接协调者, 即找到服务端中管理这个消费者的协调者节点 ...

  9. Redux 和 ngrx 创建更佳的 Angular 2

    Redux 和 ngrx 创建更佳的 Angular 2 翻译:使用 Redux 和 ngrx 创建更佳的 Angular 2 原文地址:http://onehungrymind.com/build- ...

随机推荐

  1. 用c#开发微信 (6) 微渠道 - 推广渠道管理系统 1 基础架构搭建

    我们可以使用微信的“生成带参数二维码接口”和 “用户管理接口”,来实现生成能标识不同推广渠道的二维码,记录分配给不同推广渠道二维码被扫描的信息.这样就可以统计和分析不同推广渠道的推广效果. 本系统使用 ...

  2. 一页纸商业计划书 (Business Plan) 模板(转载)

    本文转载自:https://blog.eood.cn/business-plan 假如你也有一个 idea ,但是还处于想法阶段,这个商业计划书模板能够帮你理清思路. 这个一页 BP 模板简单实用,分 ...

  3. 从源代码分析Android-Universal-Image-Loader图片下载技巧

    在手机上尤其需要考虑网络对图片下载的影响,常见的情况是在2G网络.在3G网络需要不同的下载策略,也就是说在慢速网络与快速网络中下载需要考虑不同的策略.一种常见的策略就是Android客户端和服务端相配 ...

  4. bootstrap日期选择器-datetimepicker

    地址:http://www.bootcss.com/p/bootstrap-datetimepicker/ 使用方法,html: <div class="input-append da ...

  5. Redis教程(八):事务详解

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/135.html?1455806987 一.概述: 和众多其它数据库一样,R ...

  6. atitit.插件体系设计总结o73.doc

    1. 两大类型:微内核(级联树形结构)与巨内核(管理容器,并联结构). 1 2. 通用插件接口 1 3. 插件的绑定and 初始化 2 4. 微内核插件平台设计 2 5. 参考 2 1. 两大类型:微 ...

  7. paip.myeclipse7 java webservice 最佳实践o228

    paip.myeclipse7  java webservice 最佳实践o228 java的ws实现方案:jax-ws>>xfire ws的测试工具  webservice测试调用工具W ...

  8. javaweb学习总结(十五)——JSP基础语法

    任何语言都有自己的语法,JAVA中有,JSP虽然是在JAVA上的一种应用,但是依然有其自己扩充的语法,而且在JSP中,所有的JAVA语句都可以使用. 一.JSP模版元素 JSP页面中的HTML内容称之 ...

  9. linux下安装小鹤双拼-鹤形

    首先安装小小拼音.发现小小拼音真是一个良心软件 http://yong.dgod.net/ 进入下载页面.我是下载 解压版的 解压缩后.放在主目录里.可以改成.yong 隐藏起来 安装步骤(前人栽树, ...

  10. php 3种常见设计模式

    1.工厂模式 <?php namespace Facebab; class Factory { static function createDatabase () { return new Da ...