Publish-Subscribe

NServiceBus has a built in implementation of the Publish-subscribe pattern.

publish–subscribe is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers. Instead, published messages are characterized into classes, without knowledge of what, if any, subscribers there may be. Similarly, subscribers express interest in one or more classes, and only receive messages that are of interest, without knowledge of what, if any, publishers there are.

Or in simpler terms

Subscribers let the publisher know they're interested, and the publisher stores their addresses so that it knows where to send which message.

Mechanics

Depending on the features provided by a given transport there are two possible implementations of Publish-Subscribe mechanics: "Persistence based" and "Native".

For simplicity these explanations refer to specific endpoints as "Subscribers" and "Publishers". However in reality any endpoint can be both a publisher and/or and a subscriber.

Persistence Based

Persistence based publish-subscribe is driven by subscribe and unsubscribe control messages sent by the subscriber to the publisher and relies on the publisher having access to a location to store the connection between message types and their subscribers.

Available subscription persistences include

Transports that require persistences

Subscribe

The subscribe workflow for persistence based transports is as follows

  1. Subscribers request to a publisher the intent to subscribe to certain message types.
  2. Publisher stores both the subscriber names and the message types in the persistence.
In Versions 5 and below the subscribe message contains only the transport address of the subscriber. In Versions 6 and above the message contains also the information about the logical endpoint which is requesting the subscription. This information allows Version 6 and above endpoints to publish events to scaled out MSMQ endpoints without the need for a distributor in the middle. Unfortunately since Version 5 and below endpoints are not aware of this information, they require a distributor to be placed in front of a scaled out endpoint in order to maintain the correct semantics of event messages (being delivered to a single instance of an endpoint).

Publish

The publish workflow for persistence based transports is as follows

  1. Some code (e.g. a saga or a handler) request that a message be published.
  2. Publisher queries the storage for a list of subscribers.
  3. Publisher loops through the list and sends a copy of that message to each subscriber.

Native Based

For transports that support publish–subscribe natively no persistence is required.

Transport that support native publish–subscribe

Subscribe

The subscribe workflow for native transports is as follows

  1. Subscribers send request to the broker with the intent to subscribe to certain message types.
  2. Broker stores the subscription information.

Note that in this case the publisher does not interact in the subscribe workflow.

Publish

The publish workflow for native transports is as follows

  1. Some code (e.g. a saga or a handler) request that a message be published.
  2. Publisher sends the message to the Broker.
  3. Broker sends a copy of that message to each subscriber.

Versioning subscriptions

In NServiceBus Version 3.0 and onwards subscriptions for types with the same Major version are considered compliant. This means that a subscription for MyEvent 1.1.0 will be considered valid for MyEvent 1.X.Y as well.

Version 2.X required a perfect match. This should make it easier to upgrade the publishers without affecting the subscribers.

Authorizations

In some circumstances it may not be desirable to allow any endpoints to subscribe to a given publisher or event. NServiceBus provides a way to intervene in the subscription process and decide whether a given client should be allowed to subscribe to a given message.

Subscription authorization is only available when using transports that require persistence based publish-subscribe.

The class implements the IAuthorizeSubscriptions interface, which requires the AuthorizeSubscribe and AuthorizeUnsubscribe methods. The implementation that comes in the sample doesn't do very much, returning true for both. In a real project, access some Access Control System, Active Directory, or maybe just a database to decide if the action should be allowed.

Samples

Related Articles


Last modified 2016-04-19 08:45:39Z