Typically messaging frameworks support the request/reply pattern by sending messages between client and server, using a correlation id to map response callbacks and the client’s address or inbound channel to know whom the response should be sent to. There is usually a Send mehod that takes a message in and a Reply method that takes a response message and the address/channel of the client. Other frameworks simply rely on queues and have no concept of responses at all, so you have to define queues for the client and tell the server to drop the response message there. This works well for message oriented architectures with very well defined messages.
When you have a lot of different requests/responses you’ll have to create a lot of classes to represent your messages and a lot of message handlers to handle them and give responses back. This model can lead to a very bloated architecture if you start creating messages like GetCustomerByName, GetCustomerById, ListCustomers, UpdateCustomer and such, or create a generic CustomerQueryMessage with lots of properties and one single message handler. In these cases it is much cleaner to interact between your application components using service interfaces and group related operations.
ServiceProxy is a lightweight asynchronous proxy for .NET that allows you to use service contracts in a request/reply manner with any messaging framework. It is open source and is the result of my past work with service oriented architectures using high performance messaging frameworks that had no support for services (eg: ZeroMQ, Redis, etc).
How does it work?
On the client side ServiceProxy creates interface proxies for your service contracts, intercepts all service requests, converts them to well defined messages and sends them using a messaging framework. It also has timeout support, so that when services don’t respond within the timeout period, the proxy throws a TimeoutException or if your service is asynchronous, the result Task will complete with a TimeoutException. The created proxies are cached for the next requests.
A typical usage would be to have your components depend on your service interfaces and inject ServiceProxy proxies.
On the server side ServiceProxy handles the messages received from your messaging framework, resolves/invokes the real service implementation and sends the response back. It uses the service locator pattern to resolve services, so you may use any IoC container.
The first time a service call is made for a given contract, ServiceProxy dynamically generates, compiles and caches delegates that invoke your service operations and integrate seamlessly with the ServiceProxy request/reply interface. This means it is pretty much as fast as a direct method call to your service instances, since after the first execution no reflection will be done.
Wan’t to know more? Read how ServiceProxy core components work.
How to get started?
The source code also includes two other Nuget packages: ServiceProxy.Zmq and ServiceProxy.Redis. These are fully functional implementations of the ServiceProxy request/reply model using two different messaging frameworks and can be used to get started if you don’t use already a messaging framework. If you do use one, you just need to download the ServiceProxy package and integrate with it. You can use the Zmq or the Redis package as guidelines for the integration. An end-to-end example is also included in the source code: a WebAPI that acts as the client using ServiceProxy.Zmq as the messaging framework for the services.
Having said this, ServiceProxy by itself has no builtin messaging capabilities. However it has a simple asynchronous request/reply model that is supposed to integrate seamlessly with any messaging framework. Serialization is also responsibility of the integration with other messaging frameworks, since they should already have serialization support. Note that by integrating with other messaging frameworks it isn’t meant to replace them, but to easily add Service contracts support.
ServiceProxy.Zmq is a ZeroMQ implementation for ServiceProxy, supports load balancing by having a central component acting as a queue, multiple servers and multiple clients. It uses the clrzmq ZeroMQ binding for .NET.
ServiceProxy.Redis is a Redis implementation for ServiceProxy, supports load balancing by using Redis queue primitives, multiple servers and multiple clients. It uses the Booksleeve Redis binding for .NET, although I plan to migrate it to the newly released StackExchange.Redis binding (same author of Booksleeve).
In my next posts I will write more about the Zmq and Redis implementations.
Meanwhile you can download the Nuget packages and clone/download the source code to play with it.