zoukankan      html  css  js  c++  java
  • 使用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;
    }

      这里我们将采用protoc特殊的gRPC插件从proto文件生成代码。但是,使用gRPC插件,您可以生成gRPC客户端和服务器代码,十分方便

        搭建项目

      maven配置文件:

      

      1 <properties>
      2         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      3         <grpc.version>1.13.1</grpc.version><!-- CURRENT_GRPC_VERSION -->
      4         <protobuf.version>3.5.1</protobuf.version>
      5         <protoc.version>3.5.1-1</protoc.version>
      6         <netty.tcnative.version>2.0.7.Final</netty.tcnative.version>
      7     </properties>
      8     <dependencies>
      9         <dependency>
     10             <groupId>io.dropwizard.metrics</groupId>
     11             <artifactId>metrics-core</artifactId>
     12             <version>4.0.0</version>
     13         </dependency>
     14         <dependency>
     15             <groupId>io.grpc</groupId>
     16             <artifactId>grpc-netty</artifactId>
     17             <version>${grpc.version}</version>
     18         </dependency>
     19         <dependency>
     20             <groupId>io.grpc</groupId>
     21             <artifactId>grpc-protobuf</artifactId>
     22             <version>${grpc.version}</version>
     23         </dependency>
     24         <dependency>
     25             <groupId>io.grpc</groupId>
     26             <artifactId>grpc-stub</artifactId>
     27             <version>${grpc.version}</version>
     28         </dependency>
     29         <dependency>
     30             <groupId>io.grpc</groupId>
     31             <artifactId>grpc-alts</artifactId>
     32             <version>${grpc.version}</version>
     33         </dependency>
     34         <dependency>
     35             <groupId>io.grpc</groupId>
     36             <artifactId>grpc-testing</artifactId>
     37             <version>${grpc.version}</version>
     38             <scope>test</scope>
     39         </dependency>
     40         <dependency>
     41             <groupId>io.netty</groupId>
     42             <artifactId>netty-tcnative-boringssl-static</artifactId>
     43             <version>${netty.tcnative.version}</version>
     44         </dependency>
     45         <dependency>
     46             <groupId>com.google.api.grpc</groupId>
     47             <artifactId>proto-google-common-protos</artifactId>
     48             <version>1.0.0</version>
     49         </dependency>
     50         <dependency>
     51             <groupId>com.google.protobuf</groupId>
     52             <artifactId>protobuf-java-util</artifactId>
     53             <version>${protobuf.version}</version>
     54         </dependency>
     55         <dependency>
     56             <groupId>junit</groupId>
     57             <artifactId>junit</artifactId>
     58             <version>4.12</version>
     59             <scope>test</scope>
     60         </dependency>
     61         <dependency>
     62             <groupId>org.mockito</groupId>
     63             <artifactId>mockito-core</artifactId>
     64             <version>1.9.5</version>
     65             <scope>test</scope>
     66         </dependency>
     67         <dependency>
     68             <groupId>junit</groupId>
     69             <artifactId>junit</artifactId>
     70             <version>4.12</version>
     71         </dependency>
     72     </dependencies>
     73     <build>
     74         <extensions>
     75             <extension>
     76                 <groupId>kr.motd.maven</groupId>
     77                 <artifactId>os-maven-plugin</artifactId>
     78                 <version>1.5.0.Final</version>
     79             </extension>
     80         </extensions>
     81         <plugins>
     82             <plugin>
     83                 <groupId>org.xolstice.maven.plugins</groupId>
     84                 <artifactId>protobuf-maven-plugin</artifactId>
     85                 <version>0.5.1</version>
     86                 <configuration>
     87                     <protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
     88                     <pluginId>grpc-protocol-buffers</pluginId>
     89                     <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
     90                     <!-- 使用自己从官网下的protoc -->
     91                     <!--<protocExecutable>C:/Users/14687/workspace/google/protoc-3.6.0-win32/bin</protocExecutable>-->
     92                 </configuration>
     93                 <executions>
     94                     <execution>
     95                         <goals>
     96                             <goal>compile</goal>
     97                             <goal>compile-custom</goal>
     98                         </goals>
     99                     </execution>
    100                 </executions>
    101             </plugin>
    102             <plugin>
    103                 <groupId>org.apache.maven.plugins</groupId>
    104                 <artifactId>maven-enforcer-plugin</artifactId>
    105                 <version>1.4.1</version>
    106                 <executions>
    107                     <execution>
    108                         <id>enforce</id>
    109                         <goals>
    110                             <goal>enforce</goal>
    111                         </goals>
    112                         <configuration>
    113                             <rules>
    114                                 <requireUpperBoundDeps/>
    115                             </rules>
    116                         </configuration>
    117                     </execution>
    118                 </executions>
    119             </plugin>
    120             <plugin>
    121                 <groupId>org.apache.maven.plugins</groupId>
    122                 <artifactId>maven-compiler-plugin</artifactId>
    123                 <configuration>
    124                     <source>1.8</source>
    125                     <target>1.8</target>
    126                 </configuration>
    127             </plugin>
    128         </plugins>
    129     </build>
        注意:这里的  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 {
     2     private static final Logger log = Logger.getLogger(HelloWorldServer.class.getName());
     3 
     4     private Server server;
     5 
     6     public static void main(String[] args) throws IOException, InterruptedException {
     7         final HelloWorldServer server = new HelloWorldServer();
     8         server.start();
     9         server.blockUntilShutdown();
    10     }
    11 
    12     private void start() throws IOException {
    13         int port = 50051;
    14         //1.forPort 指定监听客户端请求的端口
    15         //2.创建我们的服务端实现类的实例GreeterImpl并将传递给构建器的addService方法
    16         //3.调用build ()并 start()在构建器上为我们的服务创建和启动RPC服务器
    17         server = ServerBuilder.forPort(port)
    18                 .addService(new GreeterImpl())
    19                 .build()
    20                 .start();
    21         log.info("Server stated , listener on port:" + port);
    22         //JVM关闭时调用的钩子
    23         Runtime.getRuntime().addShutdownHook(new Thread() {
    24             @Override
    25             public synchronized void start() {
    26                 System.err.println("*** shutting down gRPC server since JVM is shutting down");
    27                 HelloWorldServer.this.stop();
    28                 System.err.println("*** server shut down");
    29             }
    30         });
    31     }
    32 
    33     private void stop() {
    34         if (null != server) {
    35             server.shutdown();
    36         }
    37     }
    38 
    39     /**
    40      * Await termination on the main thread since the grpc library uses daemon threads.
    41      *
    42      * @throws InterruptedException
    43      */
    44     private void blockUntilShutdown() throws InterruptedException {
    45         if (null != server) {
    46             server.awaitTermination();
    47         }
    48     }
    49 
    50     private class GreeterImpl extends GreeterGrpc.GreeterImplBase {
    51         /**
    52          * @param request          请求
    53          * @param responseObserver 响应观察器
    54          */
    55         @Override
    56         public void sayHello(HelloRequest request,
    57                              StreamObserver<HelloReply> responseObserver) {
    58             HelloReply reply = HelloReply.newBuilder()
    59                     .setMessage("Hello" + request.getName())
    60                     .build();
    61             //返回 reply数据
    62             responseObserver.onNext(reply);
    63             //指定完成gRPC的处理
    64             responseObserver.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仓库地址

     

  • 相关阅读:
    《Java TCP/IP Socket 编程 》读书笔记之十一:深入剖析socket——TCP套接字的生命周期
    c++实现二分查找
    hadoop序列化机制与java序列化机制对比
    C、C++中“*”操作符和“后++”操作符的优先级
    poj2774之最长公共子串
    Python之美[从菜鸟到高手]--urlparse源码分析
    (程序员面试题)字符串处理之寻找最大不重复子串
    hdu 4782 Beautiful Soupz
    教程Xcode 下编译发布与提交App到AppStore
    云端的ABAP Restful服务开发
  • 原文地址:https://www.cnblogs.com/coding400/p/9397186.html
Copyright © 2011-2022 走看看