-
Notifications
You must be signed in to change notification settings - Fork 10
Request Response
AzureNetQ also supports a Request/Response messaging pattern. This makes it easy to implement client/server applications where the client makes a request to a server which then processes the request and returns a response. Unlike traditional RPC mechanisms, an AzureNetQ request/response operation doesn't have a name, but is simply defined by the request/response message type pair.
Also, unlike traditional RPC mechanisms, including most web service toolkits, AzureNetQ's request/response pattern is based on messaging, so it is asynchronous out-of-the-box.
AzureNetQ uses Service Bus Queues as it's underlying transport mechanism for Request/Response.
To make a request with AzureNetQ, call the Request method on IBus:
var myRequest = new MyRequest { Text = “Hello Server” };
var response = bus.Request<MyRequest, MyResponse>(myRequest);
Console.WriteLine(response.Text);
Here we create a new request of type MyMessage and then call the Request method with the message as the argument. When the response returns the response message’s Text property is output to the console.
Messaging is by nature asynchronous. You send a message, then allow your program to continue with its other tasks. At some point in the future, you receive the response. With the synchronous Request method shown above, your thread will block until the response is returned. It is usually a better choice to use the RequestAsync method that returns a task:
var task = bus.RequestAsync<TestRequestMessage, TestResponseMessage>(request)
task.ContinueWith(response => {
Console.WriteLine("Got response: '{0}'", response.Result.Text);
});
Or alternatively use the async/await syntax in C# 5:
var response = await bus.RequestAsync<TestRequestMessage, TestResponseMessage>(request)
Console.WriteLine("Got response: '{0}'", response.Result.Text);
To write a server that responds to requests, simply use the IBus.Respond method like this:
bus.Respond<MyRequest, MyResponse>(request => new MyResponse { Text = “Responding to “ + request.Text});
Respond takes a single argument, a Func<TRequest, TResponse>
, that takes a request and returns a response. The same advice that applies to Subscription callbacks also applies to responders. Do not block on long-running IO operations. If you want to do long-running IO, use RespondAsync instead.
AzureNetQ also provides a RespondAsync method that takes a Func<TRequest, Task<TResponse>>
delegate. This allows you to execute long-running IO-bound operations without blocking a valuable thread
static void Main(string[] args)
{
// create a group of worker objects
var workers = new BlockingCollection<MyWorker>();
for (int i = 0; i < 10; i++)
{
workers.Add(new MyWorker());
}
// create the bus
var bus = AzureBusFactory.CreateBus("your_connection_string");
// respond to requests
bus.RespondAsync<RequestServerTime, ResponseServerTime>(request =>
Task.Factory.StartNew(() =>
{
var worker = workers.Take();
try
{
return worker.Execute(request);
}
finally
{
workers.Add(worker);
}
}));
Console.ReadLine();
bus.Dispose();
}
AzureNetQ example showing Request Response and Autosubcriber, wired up using Autofac
Coming soon
- Quick Start
- Introduction
- Casing in point: Topics and topics, Subscriptions and subscriptions
- Installing AzureNetQ
- Connecting to Service Bus
- Logging
- Publish
- Subscribe
- Request Response
- Send Receive
- Topic Based Routing
- Controlling Queue names
- Polymorphic Publish and Subscribe
- Scheduling Events with Future Publish
- Auto Subscriber
- Non Generic Publish & Subscription Extension Methods
- Replacing AzureNetQ Components
- Using a DI Container