快速阅读

生产者和消费者启动以后,都有一个接收事件,消费者是接收事件是处理调用方法以后等待生产者的返回,生产者的接收事件是处理接收生产者发送的消息,进行处理。消费者发送的时候要在回调队列中加入一个标识,标明是哪个方法进行的调用 。生产者接收到消费以后,如果发现有消息标识 ,把消息标识继续返回去,这样消费者可以保证接收到的消息是哪个方法调用的

关于RPC调用的建议

  1. 明确哪个函数是调用本地的,哪个函数是调用远程的
  2. 组合之间的依赖要清晰明了
  3. 应该能处理当远程服务挂掉的时的错误

消费者代码

主方法通过实例化rpcclient,然后调用rpcclient里面的方法,获得结果以后关闭

rpcclient的逻辑如下

  1. 声明连接和信道
  2. 创建一个回调的队列 。
  3. 定义一个消费者的事件,绑定信道。
  4. 为信道创建一个消息头,在里面标识消息id,和回调队列的名称
  5. 消费者接收事件处理,当收到消息以后,判断消息头,如果是发送的消息id,则加入到返回的消息集合中。
  6. 从消息集合中取值
static void Main(string[] args)
{
//TopicMessageTest();
RpcClient rpc = new RpcClient();
Console.WriteLine("开始启动");
var response = rpc.Call("30");
Console.WriteLine("the result is :"+response);
rpc.Close();
Console.WriteLine("调用结束");
Console.ReadLine();
}
 public class RpcClient
{ private readonly IConnection connection;
private readonly IModel channel;
private readonly string replyQueueName;
private readonly EventingBasicConsumer consumer;
private readonly IBasicProperties props; private readonly BlockingCollection<string> respQueue = new BlockingCollection<string>(); //线程安全的集合
public RpcClient()
{
var factory = new ConnectionFactory() { HostName="localhost"}; //创建一个实例 connection = factory.CreateConnection(); //创建连接 channel = connection.CreateModel(); //创建信道 replyQueueName = channel.QueueDeclare().QueueName; //创建队列 consumer = new EventingBasicConsumer(channel);//通过指定的model初台化消费者 props = channel.CreateBasicProperties(); var relationId = Guid.NewGuid().ToString();
props.CorrelationId = relationId;//应用相关标识
props.ReplyTo = replyQueueName; //回复队列指定 consumer.Received += (sender,e)=>
{
var body = e.Body;
var response = Encoding.UTF8.GetString(body);
if (e.BasicProperties.CorrelationId == relationId)
{
respQueue.Add(response);
}
}; } public string Call(string message)
{
var messageBytes = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: "", routingKey: "rpcqueue", basicProperties: props, body: messageBytes);
channel.BasicConsume(consumer: consumer, queue: replyQueueName, autoAck: true);
return respQueue.Take();
}

生产者代码

  1. 创建链接和信道
  2. 声明一个队列,指定队列名称。
  3. 配置Qos,每次取几条消息
  4. 创建消费者在接收事件中对消费者发送的消息进行处理。
  5. 事件处理中,body表示接收到的消息 ,basicProperties是消息头,对消息进行处理以后,再把消息以及消息的队列发送给消费者
static void Main(string[] args)
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{ channel.QueueDeclare(queue: "rpcqueue",durable:false,exclusive:false,autoDelete:false,arguments:null);
channel.BasicQos(0, 1, false); var consumer = new EventingBasicConsumer(channel);
channel.BasicConsume(queue: "rpcqueue", autoAck: false,consumer:consumer);
Console.WriteLine("Waiting rpc requesting"); consumer.Received += (sender, e) =>
{
string response = null;
var body = e.Body;
var props = e.BasicProperties;
var replyProps = channel.CreateBasicProperties();
replyProps.CorrelationId = props.CorrelationId; var message = Encoding.UTF8.GetString(body);
int n = int.Parse(message);
Console.WriteLine("request message is :" + message);
response = fib(n).ToString(); var responseBytes = Encoding.UTF8.GetBytes(response);
channel.BasicPublish(exchange: "", routingKey: props.ReplyTo, basicProperties: replyProps, body: responseBytes);
channel.BasicAck(deliveryTag: e.DeliveryTag, multiple: false);
};
Console.WriteLine("over");
Console.ReadLine(); } Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
} private static int fib(int n)
{
if (n == 0 || n == 1) return n;
return fib(n - 1) + fib(n - 2);
}

测试结果

友情提示

​ 我对我的文章负责,发现好多网上的文章 没有实践,都发出来的,让人走很多弯路,如果你在我的文章中遇到无法实现,或者无法走通的问题。可以直接在公众号《爱码农爱生活 》留言。必定会再次复查原因。让每一篇 文章的流程都能顺利实现。

RabbitMQ入门学习系列(七) 远程调用RPC的更多相关文章

  1. RabbitMQ入门学习系列(二),单生产者消费者

    友情提示 我对我的文章负责,发现好多网上的文章 没有实践,都发出来的,让人走很多弯路,如果你在我的文章中遇到无法实现,或者无法走通的问题.可以直接在公众号<爱码农爱生活 >留言.必定会再次 ...

  2. 转载RabbitMQ入门(6)--远程调用

    远程过程调用(RPC) (使用Java客户端) 在指南的第二部分,我们学习了如何使用工作队列将耗时的任务分布到多个工作者中. 但是假如我们需要调用远端计算机的函数,等待结果呢?好吧,这又是另一个故事了 ...

  3. RabbitMQ入门学习系列(四) 发布订阅模式

    发布订阅模式 什么时发布订阅模式 把消息发送给多个订阅者.也就是有多个消费端都完整的接收生产者的消息 换句话说 把消息广播给多个消费者 消息模型的核心 RabbitMQ不发送消息给队列,生产者也不知道 ...

  4. RabbitMQ入门学习系列(六) Exchange的Topic类型

    快速阅读 介绍exchange的topic类型,和Direct类型相似,但是增加了"."和"#"的匹配.比Direct类型灵活 Topic消息类型 特点是:to ...

  5. RabbitMQ入门学习系列(五) Exchange的Direct类型

    快速阅读 利用Exchange的Direct类型,实现对队列的过滤,消费者启动以后,输入相应的key值,攻取该key值对应的在队列中的消息 . 从一节知道Exchange有四种类型 Direct,To ...

  6. RabbitMQ入门教程(八):远程过程调用RPC

    原文:RabbitMQ入门教程(八):远程过程调用RPC 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.cs ...

  7. Bootstrap3.0入门学习系列

    Bootstrap3.0入门学习系列规划[持续更新]   前言 首先在此多谢博友们在前几篇博文当中给与的支持和鼓励,以及在回复中提出的问题.意见和看法. 在此先声明一下,之前在下小菜所有的随笔文章中, ...

  8. Asp.Net MVC5入门学习系列③

    原文:Asp.Net MVC5入门学习系列③ 添加一个视图(View) 接着上篇的入门系列,上面解说添加一个简单Controller(控制器),这里我们简单的在来添加一个View(视图)来展示我们Co ...

  9. Asp.Net MVC5入门学习系列②

    原文:Asp.Net MVC5入门学习系列② 添加一个Controller(控制器) 因为我们用的是Asp.Net MVC,MVC最终还是一套框架,所以我们还是需要遵循它才能玩下去,或者说是更好的利用 ...

随机推荐

  1. gitignore文件不生效

    git rm -r --cached . git add . git commit -m 'update .gitignore'

  2. 浅析MySQL使用 GROUP BY 分组聚合与细分聚合

    原创文章,转载请注明出处:http://www.cnblogs.com/weix-l/p/7521278.html: 若有错误,请评论指出,谢谢! 1. 聚合函数(Aggregate Function ...

  3. vs2017 官方下载地址 和 官方建立脱机安装包的方法

    vs2017 官方下载地址: https://docs.microsoft.com/zh-cn/visualstudio/releasenotes/vs2017-relnotes VS2017 官方建 ...

  4. 使用终端批量下载 B 站视频

    需要使用一个叫做 you-get 的命令行程序 可以通过 Homebrew 安装(macOS), 安装命令为 brew install you-get, 其他平台的安装可参考 Github 主页: s ...

  5. Mongodb Sharding 集群配置

    mongodb的sharding集群由以下3个服务组成: Shards  Server: 每个shard由一个或多个mongod进程组成,用于存储数据 Config  Server: 用于存储集群的M ...

  6. [LeetCode] 0155. Min Stack 最小栈 & C++Runtime加速

    题目 Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. ...

  7. Java精通并发-从Thread与Runnable说起

    java并发的学习从去年就已经中断了,之前只对于java并发的一些基础进行了一些巩固,对于这个硬技能不管是对于面试还是对于日常的实际开发来说都非常之重要,所以接下来给自己重新定一个新目标,准备重拾它一 ...

  8. 《奋斗吧!菜鸟》第九次团队作业:Beta冲刺

    项目 内容 这个作业属于哪个课程 任课教师链接 作业要求 https://www.cnblogs.com/nwnu-daizh/p/11056511.html 团队名称 奋斗吧!菜鸟 作业学习目标 B ...

  9. C++处理异常

    C++处理异常

  10. linux autofs自动挂载

    autofs:自动挂载器 自动挂载器是一个监视目录的守护进程,并在目标子目录被引用时,自动执行预定义的NFS挂载 自动挂载器由autofs服务脚本管理 自动挂载器由auto.master配置文件进行配 ...