7
votes

I am new to NServiceBus and am trying to develop a publisher and separate subscriber (I’m using v3.2.0.0) which, so far, is sort of working ok – both the publisher and subscriber are running in NServiceBus Host. My messages all publish ok but intermittently they do not get picked up by the subscriber, with the following error being displayed by the publisher:

2012-09-05 14:27:37,491 [Worker.6] WARN  NServiceBus.Unicast.UnicastBus [(null)]  <(null)> - No handlers could be found for message type: MyNamespace.MyMessage

This warning doesn’t appear for all messages though, so if I keep publishing message after message I might see half of them displaying the message and therefore not being picked up by the subscriber, although all are appearing in the MSMQ queue.

I’ll admit I’m struggling to get to grips with this, so some of my code so far may well be complete rubbish!

I am publishing messages to NSB as follows, with the message input being one of several different types I have defined:

private void Publish<T>(T message)
{
    var myBus = Configure.Instance.Builder.Build<IBus>();
    myBus.Publish(message);
}

The EndpointConfig of the publisher is as follows:

[EndpointName("MyQueue")]
public class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher, IWantCustomInitialization
{
    /// <summary>
    /// Initialisation for NServiceBus.
    /// </summary>
    public void Init()
    {
        Configure.With()
            .DefaultBuilder()
            .MsmqSubscriptionStorage()
            .DisableTimeoutManager()
            .DefiningEventsAs(t => t.Namespace != null && t.Namespace.StartsWith("MyNamespace"));
    }
}

On the subscriber side I have the following EndpointConfig:

[EndpointName("MyQueue")]
public class EndPointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
    public void Init()
    {
        Configure.With()
            .DefiningEventsAs(t => t.Namespace != null && t.Namespace.StartsWith("MyNamespace"));
    }
}

With an EventMessageHandler as follows:

public class EventMessageHandler : IEvent, IHandleMessages<IMyMessage>
{
    public void Handle(IMyMessage message)
    {
        Console.WriteLine(string.Format("Subscriber 1 received EventMessage with Id {0}.", message.Id));
    }
}

The subscriber’s app.config is:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
    <section name="MessageForwardingInCaseOfFaultConfig" type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" />
  </configSections>

  <MessageForwardingInCaseOfFaultConfig ErrorQueue="error"/>

  <UnicastBusConfig>
    <MessageEndpointMappings>
      <add Messages="MyNamespace" Endpoint="MyQueue" />
    </MessageEndpointMappings>
  </UnicastBusConfig>
</configuration>
1

1 Answers

12
votes

It looks like you are using the same endpoint name for both your publisher and your subscriber. NServiceBus uses the endpoint name to generate the queue names, so that means that both processes wind up using the same queue.

So in effect your publisher is publishing messages, but then the publisher and the subscriber are fighting over who gets to process them.

When the subscriber wins, you see your intended behavior.

When the publisher wins, there is no handler for that message, so NServiceBus displays a warning. This isn't always a problem; there are certain scenarios where you would want to receive and simply ignore a message, but this warning allows you to at least know it's happening, and in your case, it's saying that the message isn't being processed by the intended application.

So to fix it, simply change the endpoint names. MySubscriber and MyPublisher, or something like that.

You don't even need to use that attribute, you can just name the class that implements IConfigureThisEndpoint and NServiceBus will construct the endpoint name based on that. You can even use underscores such as MyProject_MyPublisher : IConfigureThisEndpoint and NServiceBus will turn the underscores into dots, so you'll get an input queue of "MyProject.MyPublisher" which is really nice for namespacing when you have many endpoints running around.