快速阅读

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

关于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. Win10同时安装office2016和visio2016说明

    前言 无论是先安装office2016还是visio2016,均不能成功. 而office2016和visio2016的镜像文件是一样的,只是名称不一样,只需下载其一即可. 具体参考链接 https: ...

  2. jar包下载网站

    https://mvnrepository.com/ https://www.kumapai.com/open/query/?querytype=title&querykey=cglib ht ...

  3. 如何导出ane所需的swc

    来源:http://blog.sina.com.cn/s/blog_6471e1bb01012ard.html 打包.ane文件的时候需要用到ActionScript的扩展库(swc文件),那么如何生 ...

  4. Spring @Transactional注解不起作用解决办法及原理分析

    Transactional失效场景介绍 第一种 Transactional注解标注方法修饰符为非public时,@Transactional注解将会不起作用.例如以下代码. 定义一个错误的@Trans ...

  5. 听说你知道什么是锁 --JAVA

    I.java中的锁 1.1 什么是锁 ​ 在计算机科学中,锁(lock)与互斥(mutex)是一种同步机制,用于在许多线程执行时对资源的限制. ​ 锁通常需要硬件支持才可以有效实施.这种支持通常采用一 ...

  6. WebStorm 2019激活方法

    1.先下载安装JetBrains WebStorm 2019,安装完成先不要运行2.接下来对软件进行注册破解,首先以记事本的方式打开hosts文件,将代码添加至hosts文件屏蔽软件联网:hosts文 ...

  7. macOS 10.13允许任何来源开启方法

    软件下载网站: http://www.pc6.com/ 软件安装问题: macOS 10.13允许任何来源开启方法: 如果需要恢复允许“任何来源”的选项,即关闭系统的Gatekeeper,我们可以在“ ...

  8. SpringBoot RabbitMQ 延迟队列代码实现

    场景 用户下单后,如果30min未支付,则删除该订单,这时候就要可以用延迟队列 准备 利用rabbitmq_delayed_message_exchange插件: 首先下载该插件:https://ww ...

  9. szwyadmin程序漏洞拿shell【方法笔记】

    我们在Google中搜索关键词 关键字:inurl:szwyadmin/login.asp 任意打开一个搜索结果,打开登录界面后在地址栏中输入下面的代码: 代码: javascript:alert(d ...

  10. c语言1博客作业08

    一.本周作业头 这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 http://edu.cnblogs.com/campus/zswxy/SE2019-3/homework/9982 我在 ...