NServiceBus作为代码跟踪机制:从类库发送消息并使用SignalR在Web应用程序上显示

时间:2011-10-12 18:48:19

标签: nservicebus signalr

我第一次努力使用NServiceBus,没有ESB背景。阅读博客文章,样本,文档等后,我无法弄清楚为什么我的C#类库不会发送消息。在Bus.Send(msg)上,我收到“没有为消息Messages.TraceStatement指定目的地。无法发送消息。请检查配置文件中的UnicastBusConfig部分,并确保消息类型存在MessageEndpointMapping。”

但首先,关于我的架构以及我想要做的事情,因为它与我在那里看到的任何样本都不同。

我的意图是使用SignalR和NServiceBus like Ben did,但有两个主要变化:

  1. 不使用NServiceBus.Host.exe。我想要一个仅限Web,没有控制台实现。
  2. 从中间层类库发送消息以进行实时代码跟踪。换句话说,我想在我的代码周围添加Bus.Send语句,从而能够在网页上查看代码执行跟踪语句(它们只是开发人员设置的临时字符串)。
  3. 假设我没有误解NServiceBus到我想象甚至不可能(或者滥用技术)的程度,我想弄清楚如何从类库中发送消息。目前我有一个“Managers”dll,它有一个app.config文件,如下所示:

    <configuration>
      <configSections>
        <section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
        <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
      </configSections>
    
        <MsmqTransportConfig InputQueue="TerminalQueue" ErrorQueue="TerminalErrorQueue" NumberOfWorkerThreads="1" MaxRetries="5"/>
    
        <UnicastBusConfig>
            <MessageEndpointMappings>
                <add Messages="Messages" Endpoint="WorkerQueue" />
            </MessageEndpointMappings>
        </UnicastBusConfig>
    </configuration>
    

    注意:在Ben的项目中,我将“Commands”重命名为“Messages”。因此(参考我帖子顶部的错误消息),据我所知,我已经正确定义了MessageEndpointMapping。 (我确认队列存在于MSMQ中。)

    谁能告诉我我做错了什么?

    另外,我非常感谢有关如何删除NServiceBus.Host.exe依赖项的输入(请参阅Ben的示例中的Worker项目)。理想情况下,类库将发送消息(就像终端在Ben的项目中所做的那样),作为订阅者,Web应用程序将能够处理事件并使用SignalR来显示消息。

    更新

    目前我已经在类库项目中抛弃了配置DLL,因为我认为Web.config会覆盖它。所以我的Web.config现在看起来有以下几点:

    <section name="microsoft.web.services3" type="Microsoft.Web.Services3.Configuration.WebServicesConfiguration, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
    <section name="MsmqSubscriptionStorageConfig" type="NServiceBus.Config.MsmqSubscriptionStorageConfig, NServiceBus.Core" />
    <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
    
    <MsmqTransportConfig
          InputQueue="WebQueue"
          ErrorQueue="WebErrorQueue"
          NumberOfWorkerThreads="1"
          MaxRetries="5"
    />
    
    <UnicastBusConfig>
        <MessageEndpointMappings>
            <add Messages="MessageEvents" Endpoint="WebQueue" />
        </MessageEndpointMappings>
    </UnicastBusConfig>
    

    我还根据http://docs.particular.net/nservicebus/messaging/publish-subscribe/创建了一个名为“NServiceBus_Subscriptions”的私有tramsactional队列。

    我的Global.asax.cs有这个:

    Bus = Configure
        .WithWeb()
            .DefaultBuilder()
            .XmlSerializer()
            .MsmqTransport()
            .PurgeOnStartup(false)
            .UnicastBus()
            .LoadMessageHandlers()
                .MsmqSubscriptionStorage()
            .CreateBus()
            .Start();
    

2 个答案:

答案 0 :(得分:1)

如果您的意图是在本地发送消息,那么您的配置是错误的。它应该是:

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

<UnicastBusConfig>
    <MessageEndpointMappings>
        <add Messages="Messages" Endpoint="WebAppQueue" />
    </MessageEndpointMappings>
</UnicastBusConfig>

但是,无需添加MessageEndpointMappings进行本地发送。您可以致电Bus.SendLocal来执行此操作。如果您要发布和订阅活动(通过Bus.Publish),那么您确实需要映射。

我最近在一台主机上发布了example。唯一的区别是您不会使用通用主机,因此您应该咨询http://docs.particular.net/samples/web/asp-mvc-application/

答案 1 :(得分:1)

这似乎是一项有趣的练习。它的实用性可能有点可疑。毕竟,MSMQ消息不能保证以任何特定顺序到达,因此很难根据收到的消息确定您的类库中发生了什么。我是否正确地阅读了正在检查的类库和诊断网页都在同一个Web应用程序中?如果是这样,使用简单的.NET事件/委托进行跟踪,然后使用SignalR将它们传送到网页将更加直接。

但就像我说的那样,这是一个有趣的练习,所以......

正如Ben的回答所示,Web应用程序向自身发送消息的配置是让MsmqTransportConfig InputQueue(接收消息的总线的“home base”)与UnicastBusConfig MessageEndpointMappings Endpoint队列匹配(它将发送消息)该类型的订阅或订阅该类型的消息。)

其他缺失的细节可能是您用于在Web应用程序中托管总线的流畅配置。您需要确保您的配置包含.LoadMessageHandlers()行,如Hosting NServiceBus in your own Process所示。 Web上的许多示例都省略了这一点,因为它们是不处理消息的仅发送端点。

另一种选择是使用Bus.SendLocal()方法,这通常是为了帮助端点将消息包拆分成不同的消息,这样每个消息都可以拥有自己的事务,但是可以在本练习中使用它来摆脱消息端点映射的要求。