0

What's the recommended messaging architecture for the following scenario:

  • Multiple workstations running a WinForms client
  • Clients must reliably notify two (or more) Windows Services of an event

Initially we wanted to avoid configuring MSMQ on the client workstations, so we created a web service. This proved difficult to configure, and then I read that publishing NServiceBus messages from a web application is not recommended.

Is the best practice to:

  • Have the clients call a web service, which sends (not publishes) a message to a Windows service, which publishes the message?
  • Send (not publish) the message directly from the client applications to a remote queue on a server, from which a Windows service publishes the message?
  • Other?

Currently I am trying to implement this using NServiceBus, but hopefully the answer is bus-agnostic.

Edit:

If clients simply send (not publish) to a remote queue, does MSMQ need to be configured (or even installed) on the client workstations? In that case what happens if the remote queue is unreachable?

TrueWill
  • 25,132
  • 10
  • 101
  • 150

2 Answers2

1

I think the clients should message the servers directly as your option two suggests. Though you would have to configure msmq on the client workstations. Why do you not want to do this?

This has the benefit of durability end-to-end.

I notice you talk about sending vs publishing, however I can't see anything in your scenario which warrants using NSB pub-sub.

FYI it's almost always the best thing to send to remote queues and read from local queues.

tom redfern
  • 30,562
  • 14
  • 91
  • 126
  • +1 and thanks. Regarding MSMQ, we were trying to minimize configuration and Things That Could Go Wrong. We'll re-think that. As for pub-sub, I thought the benefit was decoupling. If the clients send directly to the two destination queues and we want to add a third destination, don't we have to modify the clients? With pub-sub we'd just add another subscriber. Or am I missing something? – TrueWill Sep 09 '11 at 14:11
  • The problem with using pub sub is that in your scenario the clients are actually the publishers and the servers are the subscribers. It kind flips everything on it's head. The servers would then have to send a subscription message to all the client instances which existed in order to receive messages from them. It is nicer to have a subscriber send a subscription to one logical publisher (which may involve more than one queue address if you have redundancy in your setup). – tom redfern Sep 11 '11 at 12:42
  • I'm specifically avoiding making the clients publishers. My intent is to have one publisher which is a service. The servers subscribe to that. The clients simply notify the publisher of events; the publisher publishes them. In one sense yes, the clients are the "logical" publishers (but not in the scaling sense NServiceBus uses that term). But that's the business requirement. If there's a better way to implement it, that's what I'm asking. – TrueWill Sep 11 '11 at 16:11
  • OK yes I see what you are saying now. That seems like a good solution. – tom redfern Sep 11 '11 at 16:29
  • I really want to accept both answers, since you and @David both provided pieces of the puzzle. Thank you for your responses! – TrueWill Sep 12 '11 at 14:47
1

You can expose an NServiceBus endpoint as a WCF service.

From the bottom of the NServiceBus and WCF page:

public class MyService : NServiceBus.WcfService<MyCommand, MyErrorCodes>
{
    ...
}

Take a look at that. You should be able to have your client applications connect to the WCF services to drop messages. You can configure the WCF service with http, net.tcp, or whatever WCF transport works for you.

This service would then NOT be a web application, even if it uses the HTTP transport (although you might have to pick a nonstandard port). It would be a Windows service exposing a web service interface. It would be fine to publish messages from here. This gives you the freedom from having to configure MSMQ on all the clients but still a lot of the NServiceBus ease and flexibility.

Of course if scalability of this service is a concern, you may want to have an IIS-hosted web service with load balancing. In that case, create a normal WCF web service that sends a message to a NServiceBus.Host.exe endpoint installed as a Windows service, and then publish events from that Windows service.

Peter
  • 7,792
  • 9
  • 63
  • 94
David Boike
  • 18,545
  • 7
  • 59
  • 94
  • Under the hood WcfService calls bus.Send, not Publish. Do I send the MyCommand message to the InputQueue of the publisher service (that's also hosting the WcfService) and then set up a message handler that publishes it? That seems overly complex. – TrueWill Sep 09 '11 at 20:26
  • 1
    It's Bus.Send()ing MyCommand to wherever MyCommand is supposed to go. Think of MyCommand as the WCF Client to WCF Server command, or as the WSDL of the web service. All it's doing is getting the WCF request and putting it on the bus. You can specify MyCommand to go to your service's own InputQueue, and have the Handle(MyCommand) method in the very same class, and then THAT is where you would publish a different message type, the "Real message now that I live on the Service Bus" message. Hopefully that clarifies? – David Boike Sep 09 '11 at 22:10
  • @David: I thought you were not supposed to have two message types on the same queue, and that the InputQueue of a Publisher was reserved for subscription requests. Did I misunderstand? – TrueWill Sep 10 '11 at 15:33
  • 1
    @truewill - yes you have misunderstood. NServiceBus services/client all have a single input queue. This can receive any type of message. For a publisher, one of the message types it will receive on it's input queue is a subscription message. – tom redfern Sep 11 '11 at 12:39
  • 1
    The source of "one queue should only process one type of message" stems from the fact that the unit of control over scalability and your processing SLAs is the input queue. Once you process two types of messages at the same queue, you can't disentangle them or give one message type higher priority. So for the ultimate in flexibility, yes, one message type per queue, not counting administrative messages like subscription requests. – David Boike Sep 12 '11 at 20:15
  • 1
    In your situation, if load balancing the WCF service is needed, I would allow multiple WCF receivers behind a load balancer to all Bus.Send() the converted messages (via the WcfService class) to a central central endpoint that does the publishing. If scalability and reliability are not overwhelming concerns, a singular WcfService class and publisher class could coexist on the same endpoint with the same input queue. – David Boike Sep 12 '11 at 20:20