4
votes

I would like to be able to have my subscriber handling two different streams of messages. I am expecting there will be a MSMQ queue for each message type, but I don't see how to specify more than one InputQueue in the MsmqTransportConfig section in my .config file.

Here is the no-XML configuration for my subscriber:

        Configure.With(new[] { typeof(EventMessage), typeof(EventMessageHandler), typeof(NServiceBus.Unicast.Transport.CompletionMessage) })
            .CustomConfigurationSource(new UserConfigurationSource()
               .Register(() => new MsmqTransportConfig { InputQueue = "Subscriber1InputQueue", ErrorQueue = "error", NumberOfWorkerThreads = 1, MaxRetries = 5 }))
            .DefaultBuilder()
            .XmlSerializer()
            .MsmqTransport()
              .IsTransactional(true)
          .UnicastBus()
              .DoNotAutoSubscribe()
              .LoadMessageHandlers()
          .CreateBus()
          .Start();

EDIT: I seem to be getting different answers from different folks. Thanks everyone! I think I have the answer to my question and that is: A process using NServiceBus (whether publisher or subscriber) can only receive messages on a SINGLE queue. To me, this is an unnecessary limitation, and it's unfortunate that NServiceBus works this way. I don't want to have multiple processes for receiving messages, and I don't want to have them all going to the same queue. If there is a problem with a particular message handler, I would like to see only the error queue for that particular message type grow in size. I think it would allow for better visibility into what's going on in the system.

3
+1 - this is an excellent question and is something I'm struggling with as well.TrueWill

3 Answers

3
votes

haven't use a no-xml configuration yet, but with the config file it would look like:

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

<UnicastBusConfig>
    <MessageEndpointMappings>
        <add Messages="AssemblyName1" Endpoint="PublisherQueue1" />
        <add Messages="AssemblyName2.Message1, AssemblyName2" Endpoint="PublisherQueue2" />
        <add Messages="AssemblyName2.Message3, AssemblyName2" Endpoint="PublisherQueue2" />
    </MessageEndpointMappings>
</UnicastBusConfig>

so your worker queue for the current service is "WorkerQueueForCurrentService" and it subscribes to different messages that are published on the queues "PublisherQueue1" and "PublisherQueue2". i have included a sample for the subscription of a whole messageassembly (see add messages line 1) and for specific messages in a given messageassembly (see add messages line 2 and line 3).

Kristian kristensens answer is not correct. the input queue is relevant for every service that uses nservicebus. regardless of whether it's an publisher or an subscriber. a publisher receives subscription notices on the input queue and the subscriber sets the input queue as the destination queue for a subscription notice that is sent to the publisher.

if you want to programmatically subscribe to messages like mrnye says you would need a messageendpointmapping. so if you do bus.subscribe nservicebus looks into his messageendpointmappings and tries to extract the publisher queue name where this message gets published.

messageendpointmappings are used for both:
- the lookup of which messages gets published where
and
- the destination queue where messages are sent which you bus.send()

hope this clears some things up :-)

1
votes

In NServiceBus, all messages come through a single queue. It is a 1:1 mapping between queues:processes. So with your DoNotAutoSubscribe(), you just manually subscribe to the messages you want, with the mappings in your app.config

e.g., to subscribe use the function after your config

_Bus.Subscribe<SomeMessage>();

I can't remember the syntax for the message mapping sorry

1
votes

Have a look at Publish/Subscribe Configuration. The InputQueue is specified for the Publisher element and not for the subscriber. The latter adds the messages it's interested in the MessageEndpointMappings under UnicastBusConfig. If you're interested in two different streams just have to add elements under MessageEndpointMappings.