【问题标题】:In NServiceBus 6, can an endpoint subscribe to an event without knowing the publishing endpoint?在 NServiceBus 6 中,端点可以在不知道发布端点的情况下订阅事件吗?
【发布时间】:2017-06-16 17:05:57
【问题描述】:

我已更新到 NServiceBus 6,其中 IProvideConfiguration<UnicastBusConfig> 及其 MessageEndpointMappings 已过时。

我已按照文档中的发布/订阅说明进行操作。据我了解,现在需要在订阅事件时显式命名发布端点。

之前,我可以指定事件接口,端点是订阅者的名称:

config.MessageEndpointMappings.Add(
                new MessageEndpointMapping
                {
                    AssemblyName = MyAssemblyName,
                    TypeFullName = typeof( IMyEvent ) ),
                    Endpoint = "SubscribingEndpoint"
                } );

现在: 这消失了,我有以下内容。这完全取代了对 IProvideConfiguration 类的需求:

    var routing = endpointConfiguration.UseTransport<MsmqTransport>().Routing();
    endpointConfiguration.SendFailedMessagesTo( "error" );
    endpointConfiguration.AuditProcessedMessagesTo( "audit" );
    //register command
    routing.RouteToEndpoint( typeof( MyCommand), "SomeEndpoint" );
    //subscribe to event
    routing.RegisterPublisher(typeof(IMyEvent), "PublishingEndpoint" ); //?

所以在这里我必须指定 IMyEvent 的发布者,而不是订阅者。 在 NSB5 中,这不是必需的。

如果事件被多个端点发布,我该怎么办?

【问题讨论】:

  • 一个事件总是只从一个端点发布(遵循规则只有一个发布者......)并且AFAIK总是需要为事件提供发布者地址......你想做什么?
  • @SeanFarmar 我知道一个事件只能由一个端点发布。在 NSB5 中,订阅者将通过在 MessageEndpointMapping 中使用自己的端点名称而不是发布者的端点名称来订阅,如上所示。 v5 文档说了这么多。这更像是一个配置问题,而不是事件 VS 命令问题。在这种情况下发送命令会起作用,只是为它设置路由需要做更多的工作。
  • 我很困惑,您能否提供说明您可以使用端点名称而不是发布者端点名称的链接? AFAIK 订阅者总是会向发布者发送订阅消息(这是有道理的),因此它需要配置中发布者的端点名称......

标签: c# nservicebus publish-subscribe


【解决方案1】:

回答你的问题:

如果事件被多个端点发布,我该怎么办?

您可以通过多次来自订阅者的RegisterPublisher 呼叫来订阅来自多个发布者的同一事件。

请注意,如果同一事件从多个逻辑端点发布,通常会被视为异味。您可能要考虑为每个逻辑端点使用不同的事件类型,或者可能从事件切换到命令。如果您对消息设计不确定,强烈建议访问Particular Software Google Group,人们很乐意帮助您解决扩展此 SO 问题的设计问题。

关于V5和V6的变化:

在 NSB5 中,订阅者会像上面显示的那样进行订阅,方法是在 MessageEndpointMapping 中使用自己的端点名称,而不是发布者的端点名称。

我很难理解这个声明。 V5 和 V6 使用相同的订阅方法,只是语法不同。

由于您使用的是 MSMQ,订阅者必须向事件的每个发布者发送订阅消息。为了让订阅者知道将订阅消息发送到哪里,它需要为此提供路由信息。这就是 V5 和 V6 使用不同语法的地方:

  • V5 将在其 MessageEndpointMappings 中寻找匹配的路由。它将订阅消息发送到映射中指定的端点(在您的示例代码中为SubscribingEndpoint)。
  • V6 强制区分订阅消息和命令。这就是为什么有不同的 API 用于路由常规命令和路由订阅消息的原因。基于代理的传输(例如 RabbitMQ)不需要订阅消息,因此不需要为订阅消息路由,而每个传输仍然需要路由信息来发送命令。

如您所见,V5 和 V6 之间只有语法上的区别,概念上应该没有变化。既然你声称上面的例子对你有用,我只能想象几个原因:

  • 您的逻辑端点共享相同的订阅存储,这可能会导致发送到订阅者端点的订阅消息意外地对发布者可见。
  • 发布者使用的持久订阅存储已包含订阅者的订阅。尽管它可能不再接收订阅消息(因为您的配置不应该),但它仍然有一个发布者使用的“旧”订阅。

无论这些原因之一是否可以解释您看到的行为,当使用带有 NServiceBus 的 MSMQ 传输时,订阅者总是需要为发布者配置一个路由,以便订阅消息到达发布者。此设计在 V5 和 V6 之间没有变化。

有一个很好的示例演示了 V5 和 V6 中的发布/订阅,可在特定文档中找到:https://docs.particular.net/samples/pubsub/?version=core_5

我已更新到 NServiceBus 6,其中 IProvideConfiguration 及其 MessageEndpointMappings 已过时。

请注意,在 V6 中,这两个 API 都已过时并发出警告,但它们仍然可以继续工作。这些 API 将在下一个主要版本中移除。

我希望这能把事情弄清楚一点。

【讨论】:

    猜你喜欢
    • 2015-04-13
    • 2012-02-19
    • 1970-01-01
    • 2022-01-22
    • 2013-12-27
    • 1970-01-01
    • 2016-02-01
    • 2017-04-30
    • 1970-01-01
    相关资源
    最近更新 更多