使用gRPC搭建Server端与Client端
gRPC简介 gRPC是一种RPC框架技术,采用Protocal Buffers(协议缓存) 作为其接口定义的语言(就是Proto来写接口)和基础的消息交换格式。
在gRPC中,客户端应用程序可以直接调用不同机器上的服务器应用程序上的方法,就像它是本地对象一样,使您可以更轻松地创建分布式应用程序和服务。与许多RPC系统一样,gRPC基于定义服务的思想,指定可以使用其参数和返回类型远程调用的方法。在服务器端,服务器实现此接口并运行gRPC服务器来处理客户端调用。在客户端,客户端有一个存根(Stub在某些语言中称为客户端),它提供与服务器相同的方法。
文章图片
gRPC客户端和服务器可以在各种环境中相互运行和通信 - 从Google内部的服务器到您自己的桌面 - 并且可以使用任何gRPC支持的语言编写。因此,例如,您可以使用Go,Python或Ruby轻松创建Java中的gRPC服务器。此外,最新的Google API将具有gRPC版本的界面,让您可以轻松地在应用程序中构建Google功能。
使用协议缓存区(Protocal Buffers )
正如您将在我们的示例中更详细地看到的那样,您可以在普通的proto文件中定义gRPC服务,并将RPC方法参数和返回类型指定为协议缓冲区消息:
// The greeter service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} }// The request message containing the user's name. message HelloRequest { string name = 1; }// The response message containing the greetings message HelloReply { string message = 1; }
【使用gRPC搭建Server端与Client端】这里我们将采用
protoc
特殊的gRPC插件从proto文件生成代码。但是,使用gRPC插件,您可以生成gRPC客户端和服务器代码,十分方便搭建项目 maven配置文件:
1 2UTF-8 31.13.1 43.5.1 53.5.1-1 62.0.7.Final 7 89 7310 14io.dropwizard.metrics 11metrics-core 124.0.0 1315 19io.grpc 16grpc-netty 17${grpc.version} 1820 24io.grpc 21grpc-protobuf 22${grpc.version} 2325 29io.grpc 26grpc-stub 27${grpc.version} 2830 34io.grpc 31grpc-alts 32${grpc.version} 3335 40io.grpc 36grpc-testing 37${grpc.version} 38test 3941 45io.netty 42netty-tcnative-boringssl-static 43${netty.tcnative.version} 4446 50com.google.api.grpc 47proto-google-common-protos 481.0.0 4951 55com.google.protobuf 52protobuf-java-util 53${protobuf.version} 5456 61junit 57junit 584.12 59test 6062 67org.mockito 63mockito-core 641.9.5 65test 6668 72junit 69junit 704.12 7174 75 81 82 8376 80kr.motd.maven 77os-maven-plugin 781.5.0.Final 79org.xolstice.maven.plugins 84protobuf-maven-plugin 850.5.1 8687com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier} 88grpc-protocol-buffers 89io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} 90 91 92 9394 101 10210395 10096 99compile 97compile-custom 98org.apache.maven.plugins 104maven-enforcer-plugin 1051.4.1 106107 119 120121108 118enforce 109110 112enforce 111113 117114 116115 org.apache.maven.plugins 122maven-compiler-plugin 1231241.8 125 127 128 1291.8 126
注意:这里的protoc.version 和protobuf.version 需要保持一致 编写.proto文件
在 java 目录下,新建proto文件,在里面写.proto文件,如下:
syntax = "proto3"; option java_package = "com.example.service"; package helloword; // the greeter service definition service Greeter { //send a greeting rpc SayHello (HelloRequest) returns (HelloReply) { } } message HelloRequest { string name = 1; } message HelloReply { string message = 1; }
提示:用IDEA可以安装相应插件:Protobuf Support(File-->setting-->Plugins-->Browse repositories)
编写server端
文章图片
文章图片
1 public class HelloWorldServer { 2private static final Logger log = Logger.getLogger(HelloWorldServer.class.getName()); 3 4private Server server; 5 6public static void main(String[] args) throws IOException, InterruptedException { 7final HelloWorldServer server = new HelloWorldServer(); 8server.start(); 9server.blockUntilShutdown(); 10} 11 12private void start() throws IOException { 13int port = 50051; 14//1.forPort 指定监听客户端请求的端口 15//2.创建我们的服务端实现类的实例GreeterImpl并将传递给构建器的addService方法 16//3.调用build ()并 start()在构建器上为我们的服务创建和启动RPC服务器 17server = ServerBuilder.forPort(port) 18.addService(new GreeterImpl()) 19.build() 20.start(); 21log.info("Server stated , listener on port:" + port); 22//JVM关闭时调用的钩子 23Runtime.getRuntime().addShutdownHook(new Thread() { 24@Override 25public synchronized void start() { 26System.err.println("*** shutting down gRPC server since JVM is shutting down"); 27HelloWorldServer.this.stop(); 28System.err.println("*** server shut down"); 29} 30}); 31} 32 33private void stop() { 34if (null != server) { 35server.shutdown(); 36} 37} 38 39/** 40* Await termination on the main thread since the grpc library uses daemon threads. 41* 42* @throws InterruptedException 43*/ 44private void blockUntilShutdown() throws InterruptedException { 45if (null != server) { 46server.awaitTermination(); 47} 48} 49 50private class GreeterImpl extends GreeterGrpc.GreeterImplBase { 51/** 52* @param request请求 53* @param responseObserver 响应观察器 54*/ 55@Override 56public void sayHello(HelloRequest request, 57StreamObserver responseObserver) { 58HelloReply reply = HelloReply.newBuilder() 59.setMessage("Hello" + request.getName()) 60.build(); 61//返回 reply数据 62responseObserver.onNext(reply); 63//指定完成gRPC的处理 64responseObserver.onCompleted(); 65} 66} 67 }
View Code 编写client端
文章图片
文章图片
public class HelloWordClient { private static final Logger log = Logger.getLogger(HelloWordClient.class.getName()); private final ManagedChannel channel; //阻塞/同步 的stub(存根) private final GreeterGrpc.GreeterBlockingStub blockingStub; //非阻塞/异步 的stub private final GreeterGrpc.GreeterStub async; /** * Greet server. If provided, the first element of {@code args} is the name to use in the * greeting. */ public static void main(String[] args) { HelloWordClient client = new HelloWordClient("localhost", 50051); String user = "world"; try { client.greet(user); client.shutdown(); } catch (InterruptedException e) { e.printStackTrace(); } }public HelloWordClient(String host, int port) { this(ManagedChannelBuilder.forAddress(host, port) .usePlaintext() .build()); }public HelloWordClient(ManagedChannel channel) { this.channel = channel; blockingStub = GreeterGrpc.newBlockingStub(channel); async = GreeterGrpc.newStub(channel); }public void greet(String name) { log.info("Will try to greet" + name + ".."); HelloRequest request = HelloRequest.newBuilder().setName(name).build(); HelloReply response = null; try { //使用阻塞 stub调用 response = blockingStub.sayHello(request); } catch (StatusRuntimeException e) { log.info(String.format("rpc failed:%s", e.getStatus())); } log.info("Greeting: " + response.getMessage()); }public void shutdown() throws InterruptedException { channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); } }
View Code
gRPC官网
GitHub仓库地址
转载于:https://www.cnblogs.com/coding400/p/9397186.html
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- 六步搭建ES6语法环境
- iOS中的Block
- Linux下面如何查看tomcat已经使用多少线程
- 使用composer自动加载类文件
- android|android studio中ndk的使用