7

我是 NServiceBus 的新手,我正在尝试开发一个发布者和单独的订阅者(我使用的是 v3.2.0.0),到目前为止,它工作正常——发布者和订阅者都在 NServiceBus 主机中运行。我的消息都发布正常,但间歇性地它们没有被订阅者接收,发布者显示以下错误:

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

但是,并非所有消息都出现此警告,因此如果我在消息后继续发布消息,我可能会看到其中一半显示消息,因此不会被订阅者接收,尽管所有消息都出现在 MSMQ 队列中。

我承认我正在努力解决这个问题,所以到目前为止我的一些代码很可能是完全垃圾!

我按如下方式向 NSB 发布消息,消息输入是我定义的几种不同类型之一:

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

发布者的EndpointConfig如下:

[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"));
    }
}

在订阅者方面,我有以下 EndpointConfig:

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

使用 EventMessageHandler 如下:

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

订阅者的 app.config 是:

<?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>
4

1 回答 1

12

看起来您为发布者和订阅者使用相同的端点名称。NServiceBus 使用端点名称来生成队列名称,这意味着两个进程最终使用同一个队列。

因此,实际上您的发布者正在发布消息,但随后发布者和订阅者正在争夺谁来处理它们。

当订阅者获胜时,您会看到您的预期行为。

当发布者获胜时,该消息没有处理程序,因此 NServiceBus 显示警告。这并不总是一个问题。在某些情况下,您希望接收并简单地忽略一条消息,但是此警告至少可以让您知道它正在发生,并且在您的情况下,它表示该消息没有被预期的应用程序处理。

所以要修复它,只需更改端点名称。MySubscriber 和 MyPublisher,或类似的东西。

您甚至不需要使用该属性,您只需命名实现的类,IConfigureThisEndpointNServiceBus 将基于此构造端点名称。您甚至可以使用下划线,例如MyProject_MyPublisher : IConfigureThisEndpointNServiceBus 会将下划线转换为点,因此您将获得“MyProject.MyPublisher”的输入队列,当您有许多端点运行时,这对于命名空间非常有用。

于 2012-09-05T17:47:58.133 回答