快速阅读

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

关于RPC调用的建议

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

消费者代码

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

rpcclient的逻辑如下

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

生产者代码

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

测试结果

友情提示

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

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. Node学习之(第二章:http模块)

    前言 继续上一节的探讨,今天我们来聊聊Node中怎么搭建一个简单的web服务器.平时大家在撸码的过程中,经常需要向服务器发送请求,然后服务器接受请求,响应数据.今天我们就来自己手写一个简单服务器,根据 ...

  2. 【hadoop】看懂WordCount例子

    前言:今天刚开始看到map和reduce类里面的内容时,说实话一片迷茫,who are you?,最后实在没办法,上B站看别人的解说视频,再加上自己去网上查java的包的解释,终于把WordCount ...

  3. 【scala】scala安装测试

    下载安装scala:scala-2.13.1.tgz 解压: [hadoop@hadoop01 ~]$ tar -zxvf scala-2.13.1.tgz 查看目录: [hadoop@hadoop0 ...

  4. Java重试机制

    重试作用: 对于重试是有场景限制的,不是什么场景都适合重试,比如参数校验不合法.写操作等(要考虑写是否幂等)都不适合重试. 远程调用超时.网络突然中断可以重试.在微服务治理框架中,通常都有自己的重试与 ...

  5. DevOps简介_转

    转自:DevOps简介     刘大飞 DevOps 是一个完整的面向IT运维的工作流,以 IT 自动化以及持续集成(CI).持续部署(CD)为基础,来优化程式开发.测试.系统运维等所有环节. Dev ...

  6. java线程基础巩固---分析Thread的join方法详细介绍,结合一个典型案例

    关于Thread中的join方法貌似在实际多线程编程当中没怎么用过,在当初学j2se的时候倒时去学习过它的用法,不过现在早已经忘得差不多啦,所以对它再复习复习下. 首先先观察下JDK对它的介绍: 其实 ...

  7. 非正常卸载Chrome浏览器导致无法重新安装

    昨晚在使用selenium的时候,Chrome浏览器和Chromedriver.exe不兼容,前几天使用的时候都没问题,查看浏览器版本后发现浏览器已经自动升级为67版本(我之前安装的是61版本). 于 ...

  8. 实用mysql数据库命令

    连接:mysql -h主机地址 -u用户名 -p用户密码 (注:u与root可以不用加空格,其它也一样)断开:exit (回车) 创建授权:grant select on 数据库.* to 用户名@登 ...

  9. Django之路——5 Django的模板层

    你肯能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python代码之中. def current_datetime(request): now = datet ...

  10. 《你说对就队》第八次团队作业:Alpha冲刺

    <你说对就队>第八次团队作业:Alpha冲刺 项目 内容 这个作业属于哪个课程 [教师博客主页链接] 这个作业的要求在哪里 [作业链接地址] 团队名称 <你说对就队> 作业学习 ...