实现RPC

首先要弄明白,RPC是个什么东西。

(RPC) Remote Procedure Call Protocol 远程过程调用协议

在一个大型的公司,系统由大大小小的服务构成,不同的团队维护不同的代码,部署在不同的机器。但是在做开发时候往往要用到其它团队的方法,因为已经有了实现。但是这些服务部署不同的机器上,想要调用就需要网络通信,这些代码繁琐且复杂,一不小心就会写的很低效。RPC协议定义了规划,其它的公司都给出了不同的实现。比如微软的wcf,以及现在火热的WebApi。

在RabbitMQ中RPC的实现也是很简单高效的,现在我们的客户端、服务端都是消息发布者与消息接收者。

首先客户端通过RPC向服务端发出请求

我这里有一堆东西需要你给我处理一下,correlation_id:这是我的请求标识,erply_to:你处理完过后把结果返回到这个队列中。

服务端拿到了请求,开始处理并返回

correlation_id:这是你的请求标识 ,原封不动的给你。 这时候客户端用自己的correlation_id与服务端返回的id进行对比。是我的,就接收。

一些繁琐的细节rabbitmq已经为我们封装了,简单的SimpleRpcServer与SimpleRpcClient让Rpc实现的更为方便,这里可以先看一下server端

使用默认的交换机,创建一个SimpleRpcServer的实例,这里需要注意的是,SimpleRpcServer的处理应该是根据业务来的,也就是自己的。在给出的类中没有任何的实现,如果我们创建一个自己的RpcServer并且给出实现

          //创建返回一个新的频道using (var channel = RabbitMqHelper.GetConnection().CreateModel()){//创建一个rpc queuechannel.QueueDeclare("RpcQueue", true, false, false, null);SimpleRpcServer rpc = new SmsSimpleRpcServer(new Subscription(channel, "RpcQueue"));Console.WriteLine("服务端启动成功");
   rpc.MainLoop();
                Console.ReadKey();}

这里是自己的一个RpcServer,在HandleSimpleCall方法里返回对处理的回调消息,在ProcessRequest中做出具体的处理逻辑

/// <summary>/// 发送短信的Rpc/// </summary>public class SmsSimpleRpcServer : SimpleRpcServer{public SmsSimpleRpcServer(Subscription subscription) : base(subscription){}/// <summary>/// 执行完成后进行h回调/// </summary>/// <param name="isRedelivered"></param>/// <param name="requestProperties"></param>/// <param name="body"></param>/// <param name="replyProperties"></param>/// <returns></returns>public override byte[] HandleSimpleCall(bool isRedelivered, IBasicProperties requestProperties, byte[] body, out IBasicProperties replyProperties){replyProperties = null;return Encoding.UTF8.GetBytes($"给{Encoding.UTF8.GetString(body)}发送短信成功");}/// <summary>/// 进行处理/// </summary>/// <param name="evt"></param>public override void ProcessRequest(BasicDeliverEventArgs evt){// todo.....base.ProcessRequest(evt);}}

回到client端,这里的代码也是非常容易的。创建一个SimpleRpcClient,然后指定了交换机类型,因为用的是默认的,所以exchange传的是null, routingkey是我们的rpcqueue。最后调用call方法

using (var channel = RabbitMqHelper.GetConnection().CreateModel()){//创建client的rpcSimpleRpcClient client = new SimpleRpcClient(channel, new PublicationAddress(exchangeType: ExchangeType.Direct, exchangeName: string.Empty, routingKey: "RpcQueue"));bool flag = true;var sendmsg = "";while (flag){Console.WriteLine("请输入要发送的消息");sendmsg = Console.ReadLine();if (string.IsNullOrWhiteSpace(sendmsg)){Console.Write("请输入消息");continue;}var msg = client.Call(Encoding.UTF8.GetBytes(sendmsg));Console.WriteLine(Encoding.UTF8.GetString(msg));}Console.ReadKey();}

把程序运行起来

后面说一些内部的东西,其实上在创建一次SimpleRpcClient的时候都会创建一个回调队列,这个队列在程序关闭后会自动消失,所以这些建议创建一次就够了,都使用这个。如果创建多次会影响性能

在回调的时候,通过源码也可以看到判断了correlation_id的一致性

在server端也可以看到在执行Process后会发布消息到回调队列

转载于:https://www.cnblogs.com/LiangSW/p/6216537.html

RabbitMQ 实现RPC相关推荐

  1. RabbitMQ中RPC的实现及其通信机制

    RabbitMQ中RPC的实现:客户端发送请求消息,服务端回复响应消息,为了接受响应response,客户端需要发送一个回调队列的地址来接受响应,每条消息在发送的时候会带上一个唯一的correlati ...

  2. rabbitmq 简易RPC调用示例

    rabbitmq 简易RPC调用示例(后附go代码)) rabbimq 库代码获取 用例概述 客户端 服务端 rabbimq 库代码获取 https://github.com/streadway/am ...

  3. 精通RabbitMQ之RPC同步调用

    精通RabbitMQ之RPC同步调用 前面我们对应用解耦做过分析,我们能够使用消息中间件来完成应用解耦,很大一部分原因是因为我们的系统之间可以异步处理并且不关心结果回执.假如我们现在需要异步处理的结果 ...

  4. RabbitMQ之RPC实现

    2019独角兽企业重金招聘Python工程师标准>>> 什么是RPC? RPC是指远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/ ...

  5. RabbitMQ实现RPC

    一.RPC处理流程如下 当客户端启动时,创建一个匿名的回调队列(名称由RabbitMQ自动创建,如下图中的amqp.gen-Xa2-). 客户端为RPC请求设置2个属性:replyTo,设置回调队列名 ...

  6. RabbitMQ除开RPC的五种消模型----原生API

    2.五种消息模型 RabbitMQ提供了6种消息模型,但是第6种其实是RPC,并不是MQ,因此不予学习.那么也就剩下5种. 但是其实3.4.5这三种都属于订阅模型,只不过进行路由的方式不同. 通过一个 ...

  7. nodejs基于RabbitMq的RPC调用

    在微服务架构中,SpringCloud,Eureka,Dubbo,ZooKeeper这些框架再熟悉不过了,其中面向接口的远程方法调用是其主要核心功能之一,而MQ主要用来应用解耦,削峰填谷等作用:最近在 ...

  8. RabbitMQ (五)实现类似Dubbo的RPC调用

    springboot对rabbitMQ的接口做了封装,要实现 request/reponse 模式的调用,只需要调用 rabbitTemplate.convertSendAndReceive 方法即可 ...

  9. RabbitMQ消息队列(七):适用于云计算集群的远程调用(RPC)

    在云计算环境中,很多时候需要用它其他机器的计算资源,我们有可能会在接收到Message进行处理时,会把一部分计算任务分配到其他节点来完成.那么,RabbitMQ如何使用RPC呢?在本篇文章中,我们将会 ...

  10. RabbitMQ+PHP 教程六(RPC)

    (using php-amqplib) 前提必读 本教程假设RabbitMQ是安装在标准端口上运行(5672).如果您使用不同的主机.端口或凭据,则连接设置需要调整. 如果您在本教程中遇到困难,可以通 ...

最新文章

  1. WinDocks发布Windows版本的Docker引擎
  2. python异步生成器
  3. TNS-04404 dbca
  4. 操作系统使用户和计算机的接口 对吗,计算机操作系统教程--核心与设计原理习题10答案...
  5. Livy安装使用(Spark rest接口服务工具)
  6. C语言Cruskal算法查找最小生成树(附完整源码)
  7. C# IE浏览器操作类
  8. 删除WSS卸载后遗留的数据库
  9. 2019 秦皇岛 I - Invoker Gym - 102361I dp
  10. Snabbdom(虚拟dom-8-removeVnodes函数)
  11. 漫谈广告竞价模式(六)
  12. WinForm两点注意的地方
  13. Photoshop 入门教程「4」如何使用撤消命令?
  14. python基础代码大全-Python-基础汇总
  15. Mybatis阶段常用单词
  16. 清华大学推荐:这32本书籍你看过几本?
  17. VPN入门教程:基本概念、使用方法及思科模拟器实践
  18. Code_Aster comm命令文件结构与说明(by Yang 2017.3.30)
  19. 什么是软件危机?软件危机的主要表现是什么?什么是软件?什么是软件工程?什么是软件过程?软件过程与软件工程方法学有何关系?​​​​​​​什么是软件开发方法?软件开发方法主要有哪些?
  20. Linux下的关闭防火墙

热门文章

  1. logistic regression编程作业--sigmoid function,Cost function and gradient,Evaluating logistic regression
  2. Harnessing Your Zombies to Help You
  3. 多元梯度下降法演练(1)--特征缩放(特征归一化),Feature Scaling,mean normalization machine learning
  4. ios3怎么取消长按弹出菜单_iOS中长按调出菜单组件UIMenuController的使用实例
  5. 小波变换 分离影像低频部分_连续小波变换(1)
  6. hdu acm 1540
  7. Hive高级查询(group by、 order by、 join等)
  8. php autosub,教你用PHP实现微信小程序人脸识别刷脸登录功能
  9. mysql删除的方法_mysql三种删除方式
  10. Java Web GenericServlet