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. 大熊君说说JS与设计模式之------策略模式Strategy

    一,总体概要 1,笔者浅谈 策略模式,又叫算法簇模式,就是定义了不同的算法,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 策略模式和工厂模式有一定的类似,策略模式相对简单容易理解,并 ...

  2. 实验六 序列信号检测器的VHDL设计

    一.实验目的 (1)进一步熟悉Quartus II软件和GW48-PK2S实验系统的使用方法: (2)用状态机实现序列检测器的设计,了解一般状态机的设计与应用 二.实验内容 1. 基本命题 利用Qua ...

  3. Windows Phone 8 解锁提示IpOverUsbSvc问题——IpOverUsbEnum返回No connected partners found解决方案

    我的1520之前总是无法解锁,提示:IpOverUsbSvc服务没有开启什么的. 根据网上网友的各种解决方案: 1. 把手机时间设置为当前时间,并且关闭“自动设置” 2. 确保手机接入了互联网 3.确 ...

  4. OS——进程简答题(1)

    1,叙述进程和程序的主要区别. 解:进程和程序是两个既有联系又有区别的两个概念,它们的主要区别如下: (1)程序是指令的有序集合,其本身没有任何运行的含义,它是一个静态的概念.而进程是程序在处理机上的 ...

  5. ubuntu上安装mysql 编译安装

    为什么要折腾?首先说明的是ubuntu上安装mysql等软件是非常容易简单的,其简单的程度盖过windows上的安装,一句sudo apt-get install就可以搞定.如果想用最简便的方法安装m ...

  6. 安装Ubuntu14.04版本的操作系统

    1:安装好虚拟机之后便是安装操作系统,操作系统分为好多种,在这里笔者使用的是Ubuntu14.04版本的操作系统,除此之后还可以使用fedora或者小红帽等等操作系统 软件包http://pan.ba ...

  7. (一)MVC5干货篇,目录和路由

    MVC目录结构概述 文件夹或文件 描述 备注 /App_Data 此文件夹用于存放私有数据,如XML,或者SQL Server Express\SQLite的数据库文件,或其他基于文件的存储库 IIS ...

  8. curl模拟登录

    $post_data = array("username"=>"yuejide@163.com","password"=>&qu ...

  9. VS2015 ASP.NET5 Web项目结构浅析

    前言 本文个人同步博客地址http://aehyok.com/Blog/Detail/76.html 个人网站地址:aehyok.com QQ 技术群号:206058845,验证码为:aehyok 本 ...

  10. VS2015安装 Secondary Installer Setup Failed求解决方案

    个人同步本文博客地址http://aehyok.com/Blog/Detail/64.html 个人网站地址:aehyok.com QQ 技术群号:206058845,验证码为:aehyok 本文文章 ...