gRpc的四种通信方式详细介绍

🌷🍁 博主猫头虎 带您 Go to New World.✨🍁
🦄 博客首页——猫头虎的博客🎐
🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺
🌊 《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐
🌊 《100天精通Golang(基础入门篇)》学会Golang语言,畅玩云原生,走遍大小厂~💐
🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批评指正!🍁🐥
文章目录
- gRpc的四种通信方式
- 四种通信方式
- 简单RPC(一元RPC)
- 特点
- 语法
- 服务端流式RPC
- 特点
- 使用场景
- 语法
- 关键代码
- 客户端流式RPC
- 应用场景
- proto
- 开发
- 双向流式RPC
- 应用场景
- 编码
- **总结**:
- **参考资料**:
- 原创声明
gRpc的四种通信方式

四种通信方式
- 简单rpc 一元rpc (Unary RPC)
- 服务端流式RPC (Server Streaming RPC)
- 客户端流式RPC (Client Streaming RPC)
- 双向流RPC (Bi-directional Stream RPC)
摘要:
本文详细介绍了gRpc的四种主要通信方式,包括简单RPC、服务端流式RPC、客户端流式RPC和双向流式RPC。每种方式都有其特点和应用场景,以及相应的代码实现。
导语:
在分布式系统中,通信是至关重要的。gRpc作为一个高性能、开源和通用的RPC框架,为我们提供了多种通信方式。那么,这些通信方式都有哪些特点和应用场景呢?让我们一起深入了解。
引言:
“通信是连接分布式系统的桥梁,而gRpc则为我们提供了这座桥梁的多种形式。从简单的一对一通信到复杂的双向流通信,gRpc都能为我们提供稳定和高效的解决方案。”
简单RPC(一元RPC)
- 第一个RPC程序,实际上就是一元RPC
特点
当client发起调用后,提交数据,并且等待 服务端响应。开发过程中,主要采用就是一元RPC的这种通信方式。

语法
service HelloService{rpc hello(HelloRequest) returns (HelloResponse){}rpc hello1(HelloRequest1) returns (HelloResponse1){}
}
服务端流式RPC
一个请求对象,服务端可以回传多个结果对象。
特点

使用场景
client --------> Server
股票标号
<-------
某一个时刻的 股票的行情
语法
service HelloService{rpc hello(HelloRequest) returns (stream HelloResponse){}rpc hello1(HelloRequest1) returns (HelloResponse1){}
}
关键代码
服务端
public void c2ss(HelloProto.HelloRequest request, StreamObserver<HelloProto.HelloResponse> responseObserver) {//1 接受client的请求参数String name = request.getName();//2 做业务处理System.out.println("name = " + name);//3 根据业务处理的结果,提供响应for (int i = 0; i < 9; i++) {HelloProto.HelloResponse.Builder builder = HelloProto.HelloResponse.newBuilder();builder.setResult("处理的结果 " + i);HelloProto.HelloResponse helloResponse = builder.build();responseObserver.onNext(helloResponse);try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}responseObserver.onCompleted();}
客户端
public class GprcClient3 {public static void main(String[] args) {ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 9000).usePlaintext().build();try {HelloServiceGrpc.HelloServiceBlockingStub helloService = HelloServiceGrpc.newBlockingStub(managedChannel);HelloProto.HelloRequest.Builder builder = HelloProto.HelloRequest.newBuilder();builder.setName("sunshuai");HelloProto.HelloRequest helloRequest = builder.build();Iterator<HelloProto.HelloResponse> helloResponseIterator = helloService.c2ss(helloRequest);while (helloResponseIterator.hasNext()) {HelloProto.HelloResponse helloResponse = helloResponseIterator.next();System.out.println("helloResponse.getResult() = " + helloResponse.getResult());}} catch (Exception e) {e.printStackTrace();}finally {managedChannel.shutdown();}}
}监听 异步方式 处理服务端流式RPC的开发
1. api
2. 服务端
3. 客户端 public class GrpcClient4 {public static void main(String[] args) {ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 9000).usePlaintext().build();try {HelloServiceGrpc.HelloServiceStub helloService = HelloServiceGrpc.newStub(managedChannel);HelloProto.HelloRequest.Builder builder = HelloProto.HelloRequest.newBuilder();builder.setName("xiaohei");HelloProto.HelloRequest helloRequest = builder.build();helloService.c2ss(helloRequest, new StreamObserver<HelloProto.HelloResponse>() {@Overridepublic void onNext(HelloProto.HelloResponse value) {//服务端 响应了 一个消息后,需要立即处理的话。把代码写在这个方法中。System.out.println("服务端每一次响应的信息 " + value.getResult());}@Overridepublic void onError(Throwable t) {}@Overridepublic void onCompleted() {//需要把服务端 响应的所有数据 拿到后,在进行业务处理。System.out.println("服务端响应结束 后续可以根据需要 在这里统一处理服务端响应的所有内容");}});managedChannel.awaitTermination(12, TimeUnit.SECONDS);} catch (Exception e) {e.printStackTrace();} finally {managedChannel.shutdown();}}
}
客户端流式RPC
客户端发送多个请求对象,服务端只返回一个结果。

应用场景
IOT(物联网 【传感器】) 向服务端 发送数据
proto
rpc cs2s(stream HelloRequest) returns (HelloResponse){}
开发
1. apirpc cs2s(stream HelloRequest) returns (HelloResponse){}
2. 服务端开发public StreamObserver<HelloProto.HelloRequest> cs2s(StreamObserver<HelloProto.HelloResponse> responseObserver) {return new StreamObserver<HelloProto.HelloRequest>() {@Overridepublic void onNext(HelloProto.HelloRequest value) {System.out.println("接受到了client发送一条消息 " + value.getName());}@Overridepublic void onError(Throwable t) {}@Overridepublic void onCompleted() {System.out.println("client的所有消息 都发送到了 服务端 ....");//提供响应:响应的目的:当接受了全部client提交的信息,并处理后,提供相应HelloProto.HelloResponse.Builder builder = HelloProto.HelloResponse.newBuilder();builder.setResult("this is result");HelloProto.HelloResponse helloResponse = builder.build();responseObserver.onNext(helloResponse);responseObserver.onCompleted();}};}
3. 客户端开发public class GrpcClient5 {public static void main(String[] args) {ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 9000).usePlaintext().build();try {HelloServiceGrpc.HelloServiceStub helloService = HelloServiceGrpc.newStub(managedChannel);StreamObserver<HelloProto.HelloRequest> helloRequestStreamObserver = helloService.cs2s(new StreamObserver<HelloProto.HelloResponse>() {@Overridepublic void onNext(HelloProto.HelloResponse value) {// 监控响应System.out.println("服务端 响应 数据内容为 " + value.getResult());}@Overridepublic void onError(Throwable t) {}@Overridepublic void onCompleted() {System.out.println("服务端响应结束 ... ");}});//客户端 发送数据 到服务端 多条数据 ,不定时...for (int i = 0; i < 10; i++) {HelloProto.HelloRequest.Builder builder = HelloProto.HelloRequest.newBuilder();builder.setName("sunshuai " + i);HelloProto.HelloRequest helloRequest = builder.build();helloRequestStreamObserver.onNext(helloRequest);Thread.sleep(1000);}helloRequestStreamObserver.onCompleted();managedChannel.awaitTermination(12, TimeUnit.SECONDS);} catch (Exception e) {e.printStackTrace();} finally {managedChannel.shutdown();}}
}
双向流式RPC
客户端可以发送多个请求消息,服务端响应多个响应消息。

应用场景
聊天室
编码
1. apirpc cs2ss(stream HelloRequest) returns (stream HelloResponse){}
2. 服务端public StreamObserver<HelloProto.HelloRequest> cs2ss(StreamObserver<HelloProto.HelloResponse> responseObserver) {return new StreamObserver<HelloProto.HelloRequest>() {@Overridepublic void onNext(HelloProto.HelloRequest value) {System.out.println("接受到client 提交的消息 "+value.getName());responseObserver.onNext(HelloProto.HelloResponse.newBuilder().setResult("response "+value.getName()+" result ").build());}@Overridepublic void onError(Throwable t) {}@Overridepublic void onCompleted() {System.out.println("接受到了所有的请求消息 ... ");responseObserver.onCompleted();}};}
3. 客户端public class GrpcClient6 {public static void main(String[] args) {ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 9000).usePlaintext().build();try {HelloServiceGrpc.HelloServiceStub helloService = HelloServiceGrpc.newStub(managedChannel);StreamObserver<HelloProto.HelloRequest> helloRequestStreamObserver = helloService.cs2ss(new StreamObserver<HelloProto.HelloResponse>() {@Overridepublic void onNext(HelloProto.HelloResponse value) {System.out.println("响应的结果 "+value.getResult());}@Overridepublic void onError(Throwable t) {}@Overridepublic void onCompleted() {System.out.println("响应全部结束...");}});for (int i = 0; i < 10; i++) {helloRequestStreamObserver.onNext(HelloProto.HelloRequest.newBuilder().setName("sunshuai " + i).build());}helloRequestStreamObserver.onCompleted();managedChannel.awaitTermination(12, TimeUnit.SECONDS);} catch (Exception e) {e.printStackTrace();} finally {managedChannel.shutdown();}}
}
这篇博客简要介绍了gRpc的四种通信方式,包括简单RPC、服务端流式RPC、客户端流式RPC和双向流式RPC,并给出了每种方式的特点、使用场景、语法和关键代码。希望对读者有所帮助。
总结:
gRpc的四种通信方式为分布式系统提供了强大的支持。简单RPC适用于常规的请求-响应模式,服务端流式RPC和客户端流式RPC分别允许服务端和客户端发送多个消息,而双向流式RPC则支持双方的双向通信。了解这些通信方式及其应用场景,可以帮助我们更好地设计和实现分布式系统。
参考资料:
- gRpc官方文档:https://grpc.io/docs/
- “Mastering gRpc” by Alex Konrad.
- “Distributed Systems with gRpc” by Sarah Allen.

原创声明
======= ·
- 原创作者: 猫头虎
作者wx: [ libin9iOak ]
| 学习 | 复习 |
|---|---|
| ✔ |
本文为原创文章,版权归作者所有。未经许可,禁止转载、复制或引用。
作者保证信息真实可靠,但不对准确性和完整性承担责任。
未经许可,禁止商业用途。
如有疑问或建议,请联系作者。
感谢您的支持与尊重。
点击
下方名片,加入IT技术核心学习团队。一起探索科技的未来,共同成长。
相关文章:
gRpc的四种通信方式详细介绍
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
JWT令牌的介绍
目录 一、什么是JWT 二、JWT令牌和Cookie客户端、Session服务端对比 三、特点与注意事项 四、使用场景 优点: 五、结构组成 一、什么是JWT JWT(JSON Web Token)是一种用于在网络应用间传递信息的开放标准(RFC 7519&#x…...
C语言入门 Day_9 条件判断
目录 前言: 1.if判断 2.else判断 3.易错点 4.思维导图 前言: 我们知道比较运算和逻辑运算都会得到一个布尔型的数据,要么为真(true),要么为假(false)。 今天我们来学习真和假在…...
Nodejs-nrm:快速切换npm源 / npm官方源和其他自定义源之间切换
一、理解 Nodejs nrm Nodejs nrm 是一个管理 npm 源的工具。由于 npm 在国内的速度较慢,很多开发者会使用淘宝的 npm 镜像源,但是也会遇到一些问题,例如某些包在淘宝镜像源中不存在,或者淘宝镜像源本身也会有问题。 Nodejs nrm …...
数据驱动洞察:各种词频分析技术挖掘热点数据
一、引言 随着信息时代的发展,人们的关注点日益复杂多样。社交媒体、新闻网站和论坛等平台上涌现了大量的信息,这使得热点分析成为了解社会热点话题和舆情动向的重要手段。词频统计是热点分析的基础,本文将分别介绍基于ElasticSearch、基于S…...
ES6-简介、语法
ES6 ES6简介 ECMAScript 6(简称ES6)是于2015年6月正式发布的JavaScript语言的标准,正式名为ECMAScript 2015(ES2015)。它的目标是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语…...
诚迈科技子公司智达诚远与Unity中国达成合作,打造智能座舱新时代
2023 年 8 月 23 日,全球领先的实时 3D 引擎 Unity 在华合资公司 Unity 中国举办发布会,正式对外发布 Unity 引擎中国版——团结引擎,并带来专为次世代汽车智能座舱打造的团结引擎车机版。发布会上,诚迈科技副总裁、诚迈科技子公司…...
算法与数据结构(十)--图的入门
一.图的定义和分类 定义:图是由一组顶点和一组能够将两个顶点连接的边组成的。 特殊的图: 1.自环:即一条连接一个顶点和其自身的边; 2.平行边:连接同一对顶点的两条边; 图的分类: 按照连接两个顶点的边的…...
【Go 基础篇】Go语言 init函数详解:包的初始化与应用
介绍 在Go语言中,init() 函数是一种特殊的函数,用于在包被导入时执行一次性的初始化操作。init() 函数不需要手动调用,而是在包被导入时自动执行。这使得我们可以在包导入时完成一些必要的初始化工作,确保包的使用具有正确的环境…...
wazuh环境配置及漏洞复现
目录 一、wazuh配置 1进入官网下载OVA启动软件 2.虚拟机OVA安装 二、wazuh案例复现 1.wazuh初体验 2.这里我们以SQL注入为例,在我们的代理服务器上进行SQL注入,看wazuh如何检测和响应 一、wazuh配置 1进入官网下载OVA启动软件 Virtual Machine (O…...
Java接收前端请求体方式
💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! 文章目录 RequestBodyPathVariableRequestParamValidated方法参数校验方法返回值校验 RequestHeaderHttpServletRequest ## Java接收前端请求体的方式 请求体…...
私有化部署即时通讯平台,30分钟替换钉钉和企业微信
随着企业对即时通讯和协作工具的需求不断增长,私有化部署的即时通讯平台成为企业的首选。WorkPlus作为有10余年行业深耕经验与技术沉淀品牌,以其安全高效的私有化部署即时通讯解决方案,帮助企业在30分钟内替换钉钉和企业微信。本文将深入探讨…...
如何深入理解 Node.js 中的流(Streams)
Node.js是一个强大的允许开发人员构建可扩展和高效的应用程序。Node.js的一个关键特性是其内置对流的支持。流是Node.js中的一个基本概念,它能够实现高效的数据处理,特别是在处理大量信息或实时处理数据时。 在本文中,我们将探讨Node.js中的流…...
MSP430FR2xxx开发(一)添加driverlib
一、新建工程 根据自己手上的硬件型号新建工程,文中已MSP430FR2355为例。 二、添加driverlib 首先去官方下载driverlib. https://www.ti.com.cn/tool/cn/MSPDRIVERLIB?keyMatchMSP430%20DRIVERLIB#downloads 下载后的内容如下: 我这里就选择MSP430…...
【C++】做一个飞机空战小游戏(九)——发射子弹的编程技巧
[导读]本系列博文内容链接如下: 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动【C】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C】做一个飞…...
34.SpringMVC获取请求参数
SpringMVC获取请求参数 通过ServletAPI获取 将HttpServletRequest作为控制器方法的形参,此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的对象 index.html <form th:action"{/test/param}" method"post">用户名&#…...
TC1016-同星4路CAN(FD),2路LIN转USB接口卡
TC1016是同星智能推出的一款多通道CAN(FD)和LIN总线接口设备,CANFD总线速率最高支持8M bps,LIN支持速率0~20K bps,产品采用高速USB2.0接口与PC连接,Windows系统免驱设计使得设备具备极佳的系统兼容性。 支…...
Android源码——从Looper看ThreadLocal
1 概述 ThreadLocal用于在当前线程中存储数据,由于存储的数据只能在当前线程内使用,所以自然是线程安全的。 Handler体系中,Looper只会存在一个实例,且只在当前线程使用,所以使用ThreadLocal进行存储。 2 存储原理 …...
16、Flink 的table api与sql之连接外部系统: 读写外部系统的连接器和格式以及JDBC示例(4)
Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…...
MySQL 自定义 split 存储过程
MySQL 没有提供 split 函数,但可以自己建立一个存储过程,将具有固定分隔符的字符串转成多行。之所以不能使用自定义函数实现此功能,是因为 MySQL 的自定义函数自能返回标量值,不能返回多行结果集。 MySQL 8: drop pr…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
