A little background on myself: I’ve generally worked on small projects that did not require significant architecture or concerns for scaling (such as developing small scale web applications using Web Forms and MVC).
What I’m working on: I’m now building a set of WCF applications (a WCF service that routes messages between a “requester” client and a “responder” client) that needs to be stable, scalable, and obviously responsive.
What I’m doing: I have a “broker service” running two end-points, one for the requester clients and one for the responder clients. Each service and client is essentially running with WCF default values, aside from the ConcurrencyMode being set to Reentrant.
//Client
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
//Service
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant)]
Naturally, each service instance (PerSession) is independent from one another and can’t communicate with each other. So, to build a bridge between them I have a class called MessageBroker with singleton instance that the Services access. The broker routes requests from the requester service on to the responder service, and routes responses back in the same manner.
My concern is having this one object/instance route all messages for the whole system and the performance impact of that. Right now the clients are each calling their respective Send* methods using the predefined *Async methods defined when I added the service reference, and the callbacks on the clients are firing events using the Begin/End invoke methods of the event delegate. Aside from that, for now, all the methods are called synchronously. I’m thinking of adding more multithreading in the form of using the Begin/End invoke methods of a delegate in broker (I have another question about running out of threads in the threadpool using this method).
Since I’m new to this whole design/architecture concept, I want to know if what I’m doing is the right path to be taking or if I should be considering implementing a different architecture (this is the first, and seemingly the most obvious, I have come up with).
I don’t really have a mentor to bounce ideas off locally, so I hope the community can provide a little guidance.
Thanks for any advice, suggestions or criticism. 🙂
If you want your service to scale you’ll need to make the link between the participants loosely coupled. This means asynchronous queued messaging. There are countless reasons why this is a must, primarily though it would be in order to:
WCF has support for queued messaging via MSMQ, but you’ll have to forget pretty much everything about your HTTP based service model and start from scratchs with a message based paradigm. Also, you’ll need to solve the problem of authenticating and routing to/from MSMQ queues deployed on your client locations (not a trivial problem by any stretch).
You could also consider a service to provide the messaging infrastructure, like Amazon SQS.
And finally, if your back-end is SQL Server based end-to-end then you can use asynchrnous messaging straight from the database: Service Broker.