当前位置: 首页 > news >正文

gRPC-4种通信模式

4种通信模式

1、简单模式(Simple RPC)

简单模式:也称简单 RPC,即客户端发起一次请求,服务端响应处理后返回一个结果给客户端。

在 proto 文件中可如下定义:

rpc SayHello(HelloRequest) returns (HelloResponse);
2、服务端数据流模式(Server-side streaming RPC)

服务端数据流模式:也称服务端流式 RPC,即客户端发起一次请求,服务端可以连续返回数据流。
比如:客户端向服务端发送了一个查询数据库的请求,服务端持续返回多次结果。(即客户端发送一次请求,服务端查询到数据库有一万条数据,服务端分批返回10次,每次返回1000条数据给客户端)。

在 proto 文件中可如下定义:

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);

注意:在返回值前面加了stream

3、客户端数据流模式(Client-side streaming RPC)

客户端数据流模式:也称客户端流式 RPC,与服务端数据流模式相反,客户端持续向服务端发送数据流,在发送结束后,由服务端返回一个响应。
比如:客户端有一万条数据 ,分批多次请求服务端,服务端接收后把这些数据都存到数据库,然后返回一次结果给客户端。

在 proto 文件中可如下定义:

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);

注意:在参数前面加了stream

4、双向数据流模式(Bidirectional streaming RPC)

双向数据流模式:也称双向流式 RPC,即客户端和服务端都可以向对方多次收发数据。

比如:客户端有一万条数据 ,分批多次请求服务端,服务端每次接收后存到数据库后都发送一次结果给客户端。

在 proto 文件中可如下定义:

rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);

注意:参数和返回前面都加了stream

代码示例

1、简单模式

product.proto

syntax = "proto3";option java_multiple_files = true;
option java_package = "com.github.xjs.grpcapi";
option java_outer_classname = "ProductProto";package product;service ProductInfo {rpc addProduct (Product) returns (ProductId);rpc getProduct(ProductId) returns(Product);
}message Product {string id = 1;string name=2;string description=3;float price=4;
}message ProductId {string value = 1;
}

客户端:

public static void main(String[] args) {ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50050).usePlaintext().build();ProductInfoGrpc.ProductInfoBlockingStub stub = ProductInfoGrpc.newBlockingStub(channel);Product p = Product.newBuilder().setId("1").setPrice(100).setName("21天精通Java").setDescription("21天精通Java").build();ProductId productId = stub.addProduct(p);System.out.println("productId.getValue() = " + productId.getValue());Product product = stub.getProduct(ProductId.newBuilder().setValue("99999").build());System.out.println("product.getName() = " + product.getName());channel.shutdown();
}

服务端:

public class ProductInfoImpl extends ProductInfoGrpc.ProductInfoImplBase {@Overridepublic void addProduct(Product request, StreamObserver<ProductId> responseObserver) {// System.out.println("request.toString() = " + request.toString());System.out.println(TextFormat.printer().escapingNonAscii(false).printToString(request));ProductId productId = ProductId.newBuilder().setValue(request.getId()).build();responseObserver.onNext(productId);responseObserver.onCompleted();}@Overridepublic void getProduct(ProductId request, StreamObserver<Product> responseObserver) {System.out.println(TextFormat.printer().escapingNonAscii(false).printToString(request));Product product = Product.newBuilder().setId(request.getValue()).setName("三国演义").build();responseObserver.onNext(product);responseObserver.onCompleted();}
}
2、服务端数据流模式(Server-side streaming RPC)

product.proto

syntax = "proto3";option java_multiple_files = true;
option java_package = "com.github.xjs.grpcapi.clientstream";
option java_outer_classname = "ProductProto";package product.clientstream;service ProductInfo {rpc getProductBatch (ProductGetBatchRequest) returns (stream Product);
}message ProductGetBatchRequest {int32 count = 10;}message Product {string id = 1;string name=2;string description=3;float price=4;
}

客户端:

public static void main(String[] args) throws Exception {CountDownLatch countDownLatch = new CountDownLatch(1);ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50050).usePlaintext().build();ProductInfoGrpc.ProductInfoStub stub = ProductInfoGrpc.newStub(channel);// 等待接收服务端的响应StreamObserver<Product> responseObserver = new StreamObserver<Product>() {@Overridepublic void onNext(Product result) {System.out.println("服务端返回:" + result.toString());}@Overridepublic void onError(Throwable throwable) {throwable.printStackTrace();}@Overridepublic void onCompleted() {System.out.println("服务端响应完成");// 关闭channelchannel.shutdown();// 结束程序countDownLatch.countDown();}};ProductGetBatchRequest request = ProductGetBatchRequest.newBuilder().setCount(10).build();stub.getProductBatch(request, responseObserver);// 等待结束countDownLatch.await();}

服务端:

@Override
public void getProductBatch(ProductGetBatchRequest request, StreamObserver<Product> responseObserver) {int count = request.getCount();for(int i=0; i<count; i++){Product product = Product.newBuilder().setId(""+(1+1)).setName("product" + i) .setPrice(100+i).build();responseObserver.onNext(product);System.out.println("发送数据:" + product);}responseObserver.onCompleted();System.out.println("发送完成");
}
3、客户端数据流模式(Client-side streaming RPC)

product.proto

syntax = "proto3";option java_multiple_files = true;
option java_package = "com.github.xjs.grpcapi.clientstream";
option java_outer_classname = "ProductProto";package product.clientstream;service ProductInfo {rpc addProductBatch (stream Product) returns (ProductAddResult);
}message Product {string id = 1;string name=2;string description=3;float price=4;
}message ProductAddResult {int32 count = 1;
}

客户端:

public static void main(String[] args) throws Exception {CountDownLatch countDownLatch = new CountDownLatch(1);ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50050).usePlaintext().build();ProductInfoGrpc.ProductInfoStub stub = ProductInfoGrpc.newStub(channel);// 等待接收服务端的响应StreamObserver<ProductAddResult> responseObserver = new StreamObserver<ProductAddResult>() {@Overridepublic void onNext(ProductAddResult result) {System.out.println("服务端返回:" + result.toString());}@Overridepublic void onError(Throwable throwable) {throwable.printStackTrace();}@Overridepublic void onCompleted() {System.out.println("服务端响应完成");// 关闭channelchannel.shutdown();// 结束程序countDownLatch.countDown();}};StreamObserver<Product> requestObserver = stub.addProductBatch(responseObserver);for(int i=0;i<10;i++){Product p = Product.newBuilder().setId("" + (i+1)).setPrice(100).setName("21天精通Java").setDescription("21天精通Java").build();requestObserver.onNext(p);}requestObserver.onCompleted();// 等待结束countDownLatch.await();
}

服务端:

public io.grpc.stub.StreamObserver<Product> addProductBatch(io.grpc.stub.StreamObserver<ProductAddResult> responseObserver) {return new StreamObserver<Product>() {List<Product> products = new ArrayList<>();@Overridepublic void onNext(Product product) {// 接收客户端请求System.out.println(TextFormat.printer().escapingNonAscii(false).printToString(product));products.add(product);}@Overridepublic void onError(Throwable throwable) {// 错误处理throwable.printStackTrace();}@Overridepublic void onCompleted() {// 客户端请求结束,发送响应ProductAddResult result = ProductAddResult.newBuilder().setCount(products.size()).build();responseObserver.onNext(result);responseObserver.onCompleted();System.out.println("服务端响应结束");}};
}
4、双向数据流模式(Bidirectional streaming RPC)

product.proto

syntax = "proto3";option java_multiple_files = true;
option java_package = "com.github.xjs.grpcapi.bidirectionalstream";
option java_outer_classname = "ProductProto";package product.clientstream;service ProductInfo {rpc saveProductBatch (stream Product) returns (stream ProductSaveResult);
}message ProductSaveResult {bool success = 1;
}message Product {string id = 1;string name=2;string description=3;float price=4;
}

客户端:

public static void main(String[] args) throws Exception {CountDownLatch countDownLatch = new CountDownLatch(1);ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50050).usePlaintext().build();ProductInfoGrpc.ProductInfoStub stub = ProductInfoGrpc.newStub(channel);// 等待接收服务端的响应StreamObserver<ProductSaveResult> responseObserver = new StreamObserver<ProductSaveResult>() {@Overridepublic void onNext(ProductSaveResult result) {System.out.println("服务端返回:" + result.toString());}@Overridepublic void onError(Throwable throwable) {throwable.printStackTrace();}@Overridepublic void onCompleted() {System.out.println("服务端响应完成");// 关闭channelchannel.shutdown();// 结束程序countDownLatch.countDown();}};StreamObserver<Product> requestObserver = stub.saveProductBatch(responseObserver);for(int i=0; i<10; i++){Product p = Product.newBuilder().setId(""+(i+1)).setName("product"+i).setPrice(100+i).build();requestObserver.onNext(p);System.out.println("客户端发送:" + p.toString());}requestObserver.onCompleted();System.out.println("客户端发送完成");// 等待结束countDownLatch.await();
}

服务端:

@Override
public StreamObserver<Product> saveProductBatch(StreamObserver<ProductSaveResult> responseObserver) {return new StreamObserver<Product>() {@Overridepublic void onNext(Product product) {System.out.println("收到客户端请求:" + product);ProductSaveResult result = ProductSaveResult.newBuilder().setSuccess(true).build();System.out.println("发送响应");responseObserver.onNext(result);}@Overridepublic void onError(Throwable throwable) {throwable.printStackTrace();}@Overridepublic void onCompleted() {System.out.println("客户端请求完成");responseObserver.onCompleted();System.out.println("服务端响应完成");}};
}

完成的源码下载:https://github.com/xjs1919/learning-demo/tree/master/grpc-demo

相关文章:

gRPC-4种通信模式

4种通信模式 1、简单模式&#xff08;Simple RPC&#xff09; 简单模式&#xff1a;也称简单 RPC&#xff0c;即客户端发起一次请求&#xff0c;服务端响应处理后返回一个结果给客户端。 在 proto 文件中可如下定义&#xff1a; rpc SayHello(HelloRequest) returns (Hello…...

第五项修炼—系统思考

感谢合作伙伴的推荐&#xff0c;圆满结束为期两天的马上消费《第五项修炼—系统思考》项目&#xff01;这不仅是一次培训&#xff0c;更是未来实践的起点。 两天的系统思考学习让我们看到&#xff0c;在技术管理的每个决策背后&#xff0c;都蕴含着深刻的系统关联。希望各位技…...

PYNQ 框架 - VDMA驱动 - 帧缓存

目录 1. 简介 2. 代码分析 2.1 _FrameCache 类定义 2.1.1 xlnk.cma_array() 2.1.2 pointerNone 2.1.3 PynqBuffer 2.2 _FrameCache 例化与调用 2.3 _FrameCache 测试 2.4 _FrameList 类定义 2.5 _FrameList 例化与调用 2.6 _FrameList 测试 3. 帧的使用 3.1 读取帧…...

Java导出Word文档的几种方法

文章目录 1. 使用 Apache POI2. 使用 Docx4j3. 使用 JODConverter4. 使用 FreeMarker 模板 在 Java 中导出 Word 文档可以通过多种库和方法实现。以下是几种常用的方法&#xff1a; 1. 使用 Apache POI Apache POI 是一个强大的库&#xff0c;可以用来读写 Microsoft Office 格…...

OceanBase V4.3.3,首个面向实时分析场景的GA版本发布

在10月23日举办的 OceanBase年度发布会 上&#xff0c;我们怀着激动之情&#xff0c;正式向大家宣布了 OceanBase 4.3.3 GA 版的正式发布&#xff0c;这也是OceanBase 为实时分析&#xff08;AP&#xff09;场景打造的首个GA版本。 2024 年初&#xff0c;我们推出了 4.3.0 版本…...

Maven随笔

文章目录 1、什么是MAVEN2、Maven模型3、Maven仓库4、项目集成1_Idea集成Maven设置2_创建Maven项目3_POM配置详解4_maven 坐标详情5_Maven工程类型6_导入Maven项目 5、依赖管理1_依赖配置2_依赖传递3_可选依赖4_排除依赖4_可选依赖和排除依赖的区别5_依赖范围6_继承与聚合7_版本…...

牛客题目解析

一.最长回文子串 1.题目&#xff1a;给定一个仅包含小写字母的字符串&#xff0c;求它的最长回文子串的长度。 最长回文子串__牛客网 2.算法原理&#xff1a; <1>动态规划算法:O(n^2),O(n^2) 具有通性&#xff0c;凡涉及回文子串的问题都可利用此法解决 知识储备&am…...

AG32的3个ADC可以并联使用吗

AG32的3个ADC可以并联使用吗&#xff1f; Customer: 需求&#xff1a; 在t1时间段&#xff0c;用5M的速度ch1通道采样得到结果1. 在t2时间段&#xff0c;用5M的速度ch2通道采样得到结果2. 在t3时间段&#xff0c;用5M的速度ch3通道采样得到结果3. 然后如此循环 。 考虑用3…...

什么是 OpenTelemetry?

OpenTelemetry 定义 OpenTelemetry (OTel) 是一个开源可观测性框架&#xff0c;允许开发团队以单一、统一的格式生成、处理和传输遥测数据&#xff08;telemetry data&#xff09;。它由云原生计算基金会 (CNCF) 开发&#xff0c;旨在提供标准化协议和工具&#xff0c;用于收集…...

[vulnhub]DC:7

https://www.vulnhub.com/entry/dc-7,356/ 端口扫描主机发现 探测存活主机&#xff0c;178是靶机 nmap -sP 192.168.75.0/24 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-03 13:30 CST Nmap scan report for 192.168.75.1 Host is up (0.00037s l…...

个性化十足的贵族服务器,惠普ML310e Gen8,服务器中的 “潘多拉魔盒”

个性化十足的贵族服务器&#xff0c;惠普ML310e Gen8&#xff0c;服务器中的 “潘多拉魔盒” 小伙伴们大家好呀&#xff0c;这里是勤奋的凯尔森同学&#xff0c;今天给大家分享一款好玩的服务器&#xff0c;惠普ML310e Gen8 V2&#xff0c;相比大家都很熟悉HP ProLiant MicroS…...

百度社招内推

百度社招内推 「百度内推」快来投递你心仪的职位吧&#xff08; 网申链接地址&#xff1a;https://dwz.cn/ah4OUcca&#xff09;&#xff0c;填入内推码&#xff0c;完成投递&#xff0c;get内推绿色通道~我的内推码&#xff1a;IZ9PVH 内推有什么好处&#xff1a; 简历直达…...

本地部署开源在线即时通讯软件Fiora打造个人私密聊天室

文章目录 前言1.关于Fiora2.安装Docker3.本地部署Fiora4.使用Fiora5.cpolar内网穿透工具安装6.创建远程连接公网地址7.固定Uptime Kuma公网地址 前言 相信大家在聊天时候总是很没安全感&#xff0c;比如在和小姐妹背着男朋友聊一些不能说的坏话&#xff0c;或者背着女朋友和兄…...

TS(类 接口 泛型)

文章目录 类复习相关知识属性修饰符public 修饰符属性的简写形式 protected修饰符private修饰符readonly修饰符 抽象类 接口&#xff08;interface&#xff09;定义类结构定义对象结构定义函数结构接口之间的继承接口自动合并 &#xff08;可重复定义&#xff09;一些相似的概念…...

docker 启动 neo4j

docker 启动 neo4j 1. 启动2. 导入数据 1. 启动 运行下面命令启动 neo4j&#xff0c; docker run \-d \--restartalways \--publish7474:7474 --publish7687:7687 \--volume$HOME/neo4j-4.4.38/data:/data \--name neo4j-apoc-4.4.38 \-e NEO4J_dbms_allow__upgradetrue \-e …...

OPENAI官方prompt文档解析

官方文档地址:https://platform.openai.com/docs/guides/gpt-best-practices 文档中文版来源:OpenAI 官方提示工程指南 [译] | 宝玉的分享 (baoyu.io) 1.写清楚说明 如果prompt给的范围十分模糊或是过于宽泛,那么GPT就会开始猜测您想要的内容,从而导致生成的结果偏离预期. …...

【GESP】C++一级练习BCQM3092,双面打印

GESP一级知识点if分支语句和取余、整除操作练习。比较简单。 题目题解详见&#xff1a;https://www.coderli.com/gesp-1-bcqm3092/ 【GESP】C一级练习BCQM3092&#xff0c;双面打印 | OneCoderGESP一级知识点if分支语句和取余、整除操作练习。比较简单。https://www.coderli.…...

mysql--多表查询

一、联合查询 作用&#xff1a;合并结果集就是把两个select语句的查询结果合并到一起&#xff01; 合并结果集有两种方式&#xff1a; UNION&#xff1a;合并并去除重复记录&#xff0c;例如&#xff1a;SELECT * FROM t1 UNION SELECT * FROM t2&#xff1b; UNION ALL&a…...

RHCE-Web-nginx http实验和nginx https实验

一、web服务器简介 &#xff08;1&#xff09;什么是www www 是 world wide web 的缩写&#xff0c;也就是全球信息广播的意思。通常说的上网就是使用 www 来查询用户 所需要的信息。 www 可以结合文字、图形、影像以及声音等多媒体&#xff0c;并通过可以让鼠标单击超链接的…...

少儿编程学习现状洞察:青少年编程教育需求与学习频率分析

随着少儿编程教育的逐渐普及&#xff0c;越来越多的家庭开始关注孩子在编程学习中的表现。根据最新数据&#xff0c;90%的少儿编程学员保持每周至少一节课的学习频率&#xff0c;而95%的编程课程都安排在周末。特别是在8岁、10岁、12岁及15岁以上的年龄层次&#xff0c;孩子的学…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...