快速阅读

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

关于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. vue 全局挂载组件

    <!-- plugin.js --> import someComponent from './components/someComponent' export default { ins ...

  2. HTML学习摘要5

    DAY 5 HTML <address> 元素定义文档或文章的联系信息(作者/拥有者). 此元素通常以斜体显示.大多数浏览器会在此元素前后添加折行. HTML <cite> 元 ...

  3. 8. :before 和 ::before 区别?【CSS】

    单冒号(:)用于CSS3伪类 双冒号(::)用于CSS3伪元素 对于CSS2之前已有的伪元素,比如:before,单冒号和双冒号的写法::before作用是一样的.

  4. php连接mySql,加密函数

    连接MySQL mysql_connect(servername,username,password); 面向对象: <?php $servername = "localhost&qu ...

  5. python中 "is"和"=="的区别

    python中"is"和"=="区别 在做leetcode的时候,在判断两个数据是否相等时使用了python中的is not,想着入乡随俗,既然入了python ...

  6. altium designer的pcb板如何移动到原点?

    可以把所有的都选中,然后将光标移到起点处,将所有的移到原点的地方,但这种做法很多时候都不好:比较好的办法就是将原点设置到起点上来. 具体做法是:edit--origin --set. 这时光标成了十字 ...

  7. 大数据技术之Hadoop3.1.2版本完全分布式部署

    大数据技术之Hadoop3.1.2版本完全分布式部署 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.主机环境准备 1>.操作系统环境 [root@node101.yinz ...

  8. ASP.NET 中TextBox设置ReadOnly="true" 无法取到值的做法

    当 TextBox设置了ReadOnly="true" 后,要是在前台为控件添加了值,后台是取不到的,值为“空” 原理没想通,说不清楚微软是出于什么考虑的,https://www. ...

  9. GooglePlay测试支付遇到的问题

    推荐谷歌安装器,可以方便地安装谷歌框架及服务 问题列表 1.测试支付时出现:需要验证身份.您需要登录自己google账号 解决:我是使用VPN,VPN地区是日本,但我在google后台设置的发布(下载 ...

  10. 样条插值法(Java)--在本地执行

    该程序主要实现样条插值的目的,为本地执行java文件 该程序包含:样条插值法.读取文件,写入文件,字符型转double型方法等: 适合初学Java的人学习: 首次使用eclipse打jar包,中间很曲 ...