开发者

NServiceBus as code trace mechanism: Sending messages from Class Library and displaying on Web app using SignalR

I am struggling to use NServiceBus for the first time, with no ESB background. After reading blog posts, the samples, the docs, etc. I cannot figure out why my C# class library will not send messages. on Bus.Send(msg) I get "No destination specified for message Messages.TraceStatement. Message cannot be sent. Check the UnicastBusConfig section in your config file and ensure that a MessageEndpointMapping exists for the message type."

But first, a little about my architecture and what I'm trying to do, as it differs from any of the samples I've seen out there.

My intent is to use SignalR and NServiceBus like Ben did, but with two main changes:

  1. No use of NServiceBus.Host.exe. I want a Web-only, no console implementation.
  2. Messages are sent from a middle tier class library for the purpose of real-time code tracing. In other words, I want to sprinkle Bus.Send statements around my code and thereby be able to view code execution trace statements (which are just ad hoc strings set by the developer) on a Web page.

Assuming I haven't misunderstood NServiceBus to such a degree that what I envision is not even possible (or a misuse of the technology), I would like to figure out how to send messages from a class library. Currently I have a "Managers" dll that has an app.config file as follows:

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

Note: In Ben's project I renamed "Commands" to "Messages". Thus (referring to the error message at the top of my post), as far as I can tell I have properly defined a MessageEndpointMapping. (I verified that the queue exists in MSMQ.)

Can anyone tell me what I'm doing wrong?

Also, I would greatly appreciate input on how to remove the NServiceBus.Host.exe dependency (refer to the Worker project in Ben's sample). Ideally the class library would send the message (like the Terminal did in Ben's project) and the Web app would, as a subscriber, be able to handle the event and use SignalR to display the message.

UPDATE

Currently I have ditched the config DLL in the Class Library project because I would think the Web.config would cover it. So my Web.config now looks has the following:

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

I also created a private tramsactional queue called "NServiceBus_Subscriptions" as per http://docs.particular.net/nservicebus/messaging/publ开发者_如何学Goish-subscribe/.

My Global.asax.cs has this:

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


This seems like an interesting exercise. It's utility is maybe a little questionable. After all, the MSMQ messages aren't guaranteed to arrive in any particular order, so that makes it hard to tell for sure what's going on in your class library based on the messages received. Am I reading correctly that the class library being inspected and the diagnostic web page are all in the same web application? If so, it would be a lot more straightforward to use simple .NET events/delegates to do the tracing, and then deliver them to the web page with SignalR.

But like I said, it is an interesting exercise, so...

As Ben's answer shows, the configuration for a web application to send messages to itself is to have the MsmqTransportConfig InputQueue (the Bus's "home base" where it receives messages) match the UnicastBusConfig MessageEndpointMappings Endpoint queue (where it will send messages of that type to, or subscribe to messages of that type from.)

The other missing detail might be the fluent configuration you're using to host the Bus in your web application. You need to ensure that your config includes the .LoadMessageHandlers() line as shown in Hosting NServiceBus in your own Process. Many examples out on the Web omit this because they are send-only endpoints that do not process messages.

Another option is to use the Bus.SendLocal() method, which is normally to help an endpoint split out a message bundle into distinct messages so that each can have their own transaction, but could be used in this exercise to get rid of the requirement for the message endpoint mappings.


If your intent is to send messages locally then your configuration is wrong. It should be:

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

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

However, there is no need to add the MessageEndpointMappings for sending locally. You can call Bus.SendLocal to do this. If you are publishing and subscribing to events (via Bus.Publish) then you do need the mappings.

I published an example recently that does it all on one host. The only difference is you won't be using the generic host so you should consult http://docs.particular.net/samples/web/asp-mvc-application/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜