10、Request Response 请求响应

EasyNetQ也支持Request/Response消息模式。这种模式很容易实现Client/Server应用,即客户端发送一个请求给服务器,服务器处理请求然后返回一个响应。和传统的RPC(远程过程调用,如WebService)机制不同,EasyNetQ request/response操作不需要有一个名字,仅仅需要简单的定义一对request/response消息类型。

另外,不同于传统的RPC机制包括众多的web service 工具集,EasyNetQ的request/response模式是基于消息传递,因此它是开箱即用的异步模式。

发送请求,处理响应

用EasyNet发送请求,即调用IBus的Request方法。

var myRequest = new MyRequest{Text ="hello Server"};
var response = bus.Request<MyRequest, MyResponse>(myRequest);
Console.WriteLine(response.Text);

这里我们创建了一个MyRequest类型的请求(消息),和MyResponse类型的响应(消息)——简单起见,都定义一个Text自动属性,然后调用IBus的Request方法,并用这个请求消息作为它的参数。

执行Request方法时当前线程阻塞在此,直到收到一个MyResponse类型消息。当返回这个response响应时,消息的Text属性值输出到控制台。

异步请求

消息传递天生是异步的。你发送一个消息,然后允许你的程序继续执行其他任务。在之后的某一时刻,你收到响应。

使用上面所示的同步Request方法,你的线程将阻塞,直到返回响应。

通常来说,使用RequestAsync方法(异步方法)返回一个Task是比较好的选择。

var task = bus.RequestAsync<MyRequest, MyResponse>(request);
task.ContinueWith(response => {
    Console.WriteLine("Got response: '{0}'", response.Result.Text);
  });

响应请求

如果要写一个用来响应请求的服务,可以简单调用IBus.Respond方法。如下:

bus.Respond<MyRequest,MyResponse>(request =>
    new MyResponse{ Text ="Responding to " + request.Text});

Respond带有单个参数,即一个Func<TRequest, TResponse>响应委托,用来接收一个请求并返回响应。我在上节讲“订阅回调委托”时说的注意事项,也适用于此处的响应委托。即:不要进行耗时的IO操作阻塞了线程。假如你非要这么干,应该使用ResponseAsync异步方法,而不是Respond方法。

异步响应

EasynetQ提供了一个RespondAsync 方法,它带有一个Func<TRequest, Task<TResponse>>委托参数。

这允许你在不阻塞EasyNetQ订阅处理(即循环获取消息)的情况下执行耗时的IO操作。

 1 static void Main(string[] args)
 2 {
 3     //创建一个工作者容器。
 4     var workers = new BlockingCollection<MyWorkder>();
 5     for(int i = 0; i < 10; i++)
 6     {
 7         workers.Add(new MyWorker());
 8     }
 9     //创建一个Bus
10     var bus = RabbitHutch.CreateBus("host=localhost");
11     //响应请求。
12     bus.RespondAsync<RequestServerTime, ResponseServerTime>( 
13         request =>
14             Task.Factory.StartNew(() =>
15             {
16                 var worker = workers.Take();
17                 try
18                 {
19                     return worker.Execute(request);
20                 }
21                 finally
22                 {
23                     workers.Add(worker);
24                 }
25             }));
26     Console.ReadLine();
27     bus.Dispose();
28 }


示例应用

EasynetQ展示Request Response和Autosubcriber,连上使用Windsor IOC的示例代码地址如下:
https://bitbucket.org/philipogorman/createrequestservice/src

英文地址:https://github.com/EasyNetQ/EasyNetQ/wiki/Request-Response

posted on 2017-12-05 11:16  困兽斗  阅读(824)  评论(0编辑  收藏  举报

导航