Syg
Syg

Reputation: 403

is NServiceBus useful in this WCF MVC scenario?

I just started investigating nservicebus, and can't figure out of it's appropriate or maybe overkill for my particular situation. Architectural pointers are greatly appreciated, i'm struggling a bit.

I have an MVC website and WCF REST service that both receive messages, e.g. "post a question". This should trigger a number of actions, like storage of the enity, examiniation by a rules engine, and maybe sending a push message, updating some aggregate data. The result of the rules engine might also cause a new message to be created. These requirements may change in the future. I would like to implement this in a way where the receiving endpoint sends out a message to anyone who happens to be listening (person X created a new question).

I was thinking of storing the messages in a db table and having my modules monitor the table. This thought process was moved to msmq and then to pub sub using nservicebus. However, I'm not sure how this should be implemented.

I'm currently thinking about the following scenario. A question comes into the WCF REST service. The WCF service persists the question and publishes a new question message (so it would need to host nservicebus somehow?). My modules subscribed to the message take action, like send out a notification or trigger an action based on the defined rules.

Is this a scenario where pub sub using nservicebus will benefit me? And would this be the way to go about actually implmenting it?

Upvotes: 3

Views: 1300

Answers (3)

tom redfern
tom redfern

Reputation: 31760

The WCF service persists the question and publishes a new question message (so it would need to host nservicebus somehow?)

NServiceBus can be hosted in any managed process, including IIS. To do this (inside WCF service)

  • Create an instance of IBus when your WCF service starts up.
  • When you receive a question request into the service assemble your NServiceBus message
  • Publish the messages by using IBus.Publish(MyMessage);

To create an instance of IBus in IIS a common method is to use the fluent configuration inside your global asmx. A typical configuration would look something like

public class Global : System.Web.HttpApplication
{
    public static IBus Bus { get; private set; }

    void Application_Start(object sender, EventArgs e)
    {
        Bus = NServiceBus.Configure.WithWeb()
            .Log4Net()
            .DefaultBuilder()
            .XmlSerializer()
            .MsmqTransport()
                .IsTransactional(false)
                .PurgeOnStartup(false)
            .UnicastBus()
                .ImpersonateSender(false)
            .CreateBus()
            .Start();
    } 

You define your NServiceBus endpoint (Queues) using the web.config:

<configSections>
    <section name="MsmqTransportConfig" 
             type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
</configSections>

<MsmqTransportConfig InputQueue="WebFrontEnd" 
                     ErrorQueue="error" 
                     NumberOfWorkerThreads="1" 
                     MaxRetries="5" />

My modules subscribed to the message take action

Your downstream subscribers can each be hosted inside the NServiceBus generic host running as a windows service, which is probably the easiest hosting option. The subscribers would each have a message handler class which implements IHandleMessages.

The way pub/sub works in NServiceBus:

  1. A publisher service has an input queue and a subscription store.
  2. A subscriber service has an input queue
  3. The subscriber, on start-up will send a subscription message to the input queue of the publisher
  4. The subscription message contains the type of message subscriber is interested in and the subscribers queue address
  5. The publisher records the subscription in the subscription store.
  6. The publisher receives a message.
  7. The publisher evaluates the message type against the list of subscriptions
  8. For each match found the publisher sends the message to the queue address.

You should probably download the NServiceBus pub-sub sample to gain a better understanding of this.

Upvotes: 2

Adam Fyles
Adam Fyles

Reputation: 6050

I'm going to assume that your REST API is handling GETs and you'd like to turn some of your PUTs/POSTs/DELETEs into "async" calls. You can use the built-in WCF integration endpoint, but you are tied to a SOAP binding. You can hack in REST, but now you have essentially 2 endpoints, one for GETs and one for everything else.

We've integrated the two but bootstrapping NSB into WCF similar to the other answer(we use a HttpModule). For change operations, we simply Bus.Send() the message to another endpoint and return to the client. The receiving endpoint simply processes the message as needed.

If you require a pipeline of logic, that is built-in. You can string message handlers together to process in a defined sequence. I'm thinking you may not need Pub/Sub at all if this is the effect you desire. This keeps down the number of endpoints. If the endpoint gets overloaded, we can scale out by adding a Distributor, but that is another story.

Upvotes: 2

Jason Meckley
Jason Meckley

Reputation: 7591

I think you would use NSB in place of WCF, not in addition to WCF. Service Buses introduce many new concepts and designs. the idea of asynchronous work is very different that traditional request/response.

To start, I would introduce a service bus until it's needed, that is until the request/response design becomes the bottleneck itself. A service bus isn't something you just "drop in" to an application. when introducing a service bus to an existing application you have to think through how eventually processing the command/event/message will impact the system which was designed using an imediate response & request.

Upvotes: 2

Related Questions