0
votes

Im trying to setup an NServiceBus PubSub example which is hosted inside a set of windows services.

I have configured my publisher and can see it calling my buses publish method. Ive also configured a subscriber to listen to the messages i am sending. It appears however that the actual subscription process hasnt worked properly as i cant see a log message saying the subscriber has been subscribed (as i do in the PubSub sample).

Im just wondering if you need some kind of magic to make this work when hosting the service yourself.

below is my config

Publisher

App.Config

 <configSections>
    <section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
    <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
  </configSections>
  <!-- 1. In order to configure remote endpoints use the format: "queue@machine" 
       2. Input queue must be on the same machine as the process feeding off of it.
       3. Error queue can (and often should) be on a different machine.
       4. The community edition doesn't support more than one worker thread.
  -->

  <MsmqTransportConfig InputQueue="publisher.input" ErrorQueue="error" NumberOfWorkerThreads="1" MaxRetries="5" />
  <UnicastBusConfig>
    <MessageEndpointMappings></MessageEndpointMappings>
  </UnicastBusConfig>

Bus Setup:

var bus = Configure.With()
            .Log4Net()
            .NinjectBuilder()
            .XmlSerializer()
            .MsmqSubscriptionStorage()
            .MsmqTransport()
                .IsTransactional(false)
                .PurgeOnStartup(false)
            .UnicastBus()
                .ImpersonateSender(false)
            .CreateBus()
            .Start();

Subscriber

App.Config

<configSections>
    <section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
    <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
  </configSections>
  <!-- 1. In order to configure remote endpoints use the format: "queue@machine" 
       2. Input queue must be on the same machine as the process feeding off of it.
       3. Error queue can (and often should) be on a different machine.
       4. The community edition doesn't support more than one worker thread.
  -->

  <MsmqTransportConfig
    InputQueue="subscriber.input"
    ErrorQueue="error"
    NumberOfWorkerThreads="1"
    MaxRetries="5"
  />

  <UnicastBusConfig>
    <MessageEndpointMappings>
      <add Messages="MyEventNamespace" Endpoint="publisher.input" />
    </MessageEndpointMappings>
  </UnicastBusConfig>

Bus Setup:

        var bus = Configure.With()
            .Log4Net()
            .NinjectBuilder()
            .XmlSerializer()
            .MsmqSubscriptionStorage()
            .MsmqTransport()
                .IsTransactional(false)
                .PurgeOnStartup(false)
            .UnicastBus()
                .ImpersonateSender(false)
            .CreateBus()
            .Start();

Is there anything I'm missing or doing stupidly?

Cheers

3
Can you show the roles you are using(AsA_Publisher etc.)?Adam Fyles
I thought the AsA_Publisher only worked when hosted by nservicebus? i dont have oneNot loved
I was assuming that you were, if you are not then you need to do explicit subscriptions per the post below. If you use the generic host, this work is done for you.Adam Fyles
Adam, the host is not what is responsible for automatic subscribing.Udi Dahan

3 Answers

3
votes

The main problem is that you haven't called .LoadMessageHandlers() after .UnicastBus() in your subscriber. As a result, it doesn't know that you have a handler for the event that is configured to come from publisher.input and, as a result, doesn't subscribe.

One other thing, you don't need to include the .MsmqSubscriptionStorage() for the subscriber.

1
votes

In the subscriber you can make a call to Bus.Subscribe() and set it up explicitly.

1
votes

For anyone using "Unobtrusive Mode" you should also ensure you have a message convention defined.

Somewhere I saw an example that had added this to the message handler's project:

class MessageConventions : IWantToRunBeforeConfiguration { 
   public void Init() {
      Configure.Instance.DefiningMessagesAs(t => t.Namespace != null &&  
            t.Namespace.StartsWith("Your.Messages.Namespace.Here"));
   }
}

which worked for me.

The example code here contains something similar.