社区精选|一个简单的案例入门 gRPC
今天小编为大家带来的是社区作者 江南一点雨 的文章,让我们一起来学习 gRPC 。
├── grpc-api
│ ├── pom.xml
│ ├── src
├── grpc-client
│ ├── pom.xml
│ ├── src
├── grpc-server
│ ├── pom.xml
│ ├── src
└── pom.xml
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.52.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.52.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.52.1</version>
</dependency>
<dependency> <!-- necessary for Java 9+ -->
<groupId>org.apache.tomcat</groupId>
<artifactId>annotations-api</artifactId>
<version>6.0.53</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.21.7:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.51.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
syntax = "proto3";
option java_multiple_files = true;
option java_package = "org.javaboy.grpc.demo";
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;
}
syntax = "proto3";:这个是 protocol buffers 的版本。
option java_multiple_files = true;:这个字段是可选的,如果设置为 true,表示每一个 message 文件都会有一个单独的 class 文件;否则,message 全部定义在 outerclass 文件里。
option java_package = "org.javaboy.grpc.demo";:这个字段是可选的,用于标识生成的 java 文件的 package。如果没有指定,则使用 proto 里定义的 package,如果package 也没有指定,那就会生成在根目录下。
option java_outer_classname = "ProductProto";:这个字段是可选的,用于指定 proto 文件生成的 java 类的 outerclass 类名。什么是 outerclass?简单来说就是用一个 class 文件来定义所有的 message 对应的 Java 类,这个 class 就是 outerclass;如果没有指定,默认是 proto 文件的驼峰式;
package product;:这个属性用来定义 message 的包名。包名的含义与平台语言无关,这个 package 仅仅被用在 proto 文件中用于区分同名的 message 类型。可以理解为 message 全名的前缀,和 message 名称合起来唯一标识一个 message 类型。当我们在 proto 文件中导入其他 proto 文件的 message,需要加上 package 前缀才行。所以包名是用来唯一标识 message 的。
service:我们定义的跨平台方法都写在 service 中,上面的案例中我们定义了两个方法:addProduct 表示添加一件商品,参数是一个 Product 对象,返回值则是刚刚添加成功的商品的 ID;getProduct 则表示根据 ID 查询一个商品,参数是一个商品 ID,返回值则是查询到的商品对象。这里的定义相当于一个接口,将来我们要在 Java 代码中实现这个接口。
message:这里有点像我们在 Java 中定义类,上文中我们定义了两个类,分别是 Product 和 ProductId 两个类。这两个类在 service 中被使用。
public class ProductInfoImpl extends ProductInfoGrpc.ProductInfoImplBase {
@Override
public void addProduct(Product request, StreamObserver<ProductId> responseObserver) {
System.out.println("request.toString() = " + request.toString());
responseObserver.onNext(ProductId.newBuilder().setValue(request.getId()).build());
responseObserver.onCompleted();
}
@Override
public void getProduct(ProductId request, StreamObserver<Product> responseObserver) {
responseObserver.onNext(Product.newBuilder().setId(request.getValue()).setName("三国演义").build());
responseObserver.onCompleted();
}
}
public class ProductInfoServer {
Server server;
public static void main(String[] args) throws IOException, InterruptedException {
ProductInfoServer server = new ProductInfoServer();
server.start();
server.blockUntilShutdown();
}
public void start() throws IOException {
int port = 50051;
server = ServerBuilder.forPort(port)
.addService(new ProductInfoImpl())
.build()
.start();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
ProductInfoServer.this.stop();
}));
}
private void stop() {
if (server != null) {
server.shutdown();
}
}
private void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
}
public class ProductClient {
public static void main(String[] args) {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
.usePlaintext()
.build();
ProductInfoGrpc.ProductInfoBlockingStub stub = ProductInfoGrpc.newBlockingStub(channel);
Product p = Product.newBuilder().setId("1")
.setPrice(399.0f)
.setName("TienChin项目")
.setDescription("SpringBoot+Vue3实战视频")
.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.toString() = " + product.toString());
}
}
好啦,一个简单的例子,小伙伴们先对 gRPC 入个门,后面松哥会再整几篇文章跟大家介绍这里边的一些细节。
点击左下角阅读原文,到 SegmentFault 思否社区 和文章作者展开更多互动和交流,“公众号后台“回复“ 入群 ”即可加入我们的技术交流群,收获更多的技术文章~
- END -
关注公众号:拾黑(shiheibook)了解更多
赞助链接:
关注数据与安全,洞悉企业级服务市场:https://www.ijiandao.com/
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
随时掌握互联网精彩
- Cool Admin Midway高效强大的中后台管理系统
- PG Back Web2.0,轻松备份 PostgreSQL!
- 欧元人民币汇率2023年7月16日
- 美元兑人民币汇率2023年5月20日
- 2022-2023年中国普惠小微金融高质量发展研究报告
- “Web 3+传统行业” 下一个风口?
- iPhone 15 高端版本万元起步; Arm 确认对华禁售先进芯片设计产品|思否周刊
- G20金融稳定委员会将推出全球性的加密货币监管规则
- 开发者执意造轮子,虽然结果早已命中注定
- 显卡暴降,可以买了吗?
- 像 C 一样快,Ruby 般丝滑的 Crystal 发布 1.0 版本,你看好吗?
- 请注意,标清频道将逐步关停!