美文网首页
gRPC入门-Hello World

gRPC入门-Hello World

作者: ted005 | 来源:发表于2018-09-16 23:17 被阅读143次

    本文是gRPC的一个简单例子,以protocol buffers 3作为契约类型,使用gRPC自动生成服务端和客户端代码,实现服务的远程调用。

    示例代码-Github地址

    gRPC
    • 创建gradle类型工程,build.gradle文件如下,包含了根据.proto自动生成代码的插件.

      apply plugin: 'java'
      apply plugin: 'com.google.protobuf'
      
      buildscript {
          repositories {
              maven {
                  url "http://maven.aliyun.com/nexus/content/groups/public/" }
          }
          dependencies {
              classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.5'
          }
      }
      
      repositories {
          maven {
              url "http://maven.aliyun.com/nexus/content/groups/public/" }
          mavenLocal()
      }
      
      def grpcVersion = '1.14.0'
      def nettyTcNativeVersion = '2.0.7.Final'
      def protobufVersion = '3.5.1'
      
      dependencies {
          compile "com.google.api.grpc:proto-google-common-protos:1.0.0"
          compile "io.grpc:grpc-alts:${grpcVersion}"
          compile "io.grpc:grpc-netty:${grpcVersion}"
          compile "io.grpc:grpc-protobuf:${grpcVersion}"
          compile "io.grpc:grpc-stub:${grpcVersion}"
          compileOnly "javax.annotation:javax.annotation-api:1.2"
          compile "io.netty:netty-tcnative-boringssl-static:${nettyTcNativeVersion}"
          compile "com.google.protobuf:protobuf-java-util:${protobufVersion}"
      }
      
      protobuf {
          protoc {
              artifact = "com.google.protobuf:protoc:3.5.1-1"
          }
          plugins {
              grpc {
                  artifact = 'io.grpc:protoc-gen-grpc-java:1.15.0'
              }
          }
          generateProtoTasks {
              all()*.plugins {
                  grpc {}
              }
          }
      }
      
    • 创建目录src/main/proto,并在其中新建契约文件helloworld.proto。这里定义一个请求类型HelloRequest、一个响应类型HelloReply,和一个简单的服务(serviceGreeterGreeter只提供一个简单的RPC服务(simple RPCsayHello

      syntax = "proto3";
      
      package com.mattie.grpc;
      
      option java_package = "com.mattie.grpc";
      option java_outer_classname = "HelloWorldProtos";
      
      service Greeter {
        rpc SayHello (HelloRequest) returns (HelloReply) {}
      }
      
      message HelloRequest {
        string message = 1;
      }
      
      message HelloReply {
        string message = 1;
      }
      
    • 运行命令gradle clean build,在工程目录下会生成 build文件夹,其中generated目录下包含由插件io.grpc:protoc-gen-grpc-java所生成的RPC代码。

      生成的代码目录
    • 生成的GreeterGrpc.java中包含自定义服务需要继承的抽象类GreeterImplBase,以及stub
      GreeterStub(异步返回response)和GreeterBlockingStub(同步等待response)。客户端通过stub调用服务端。

      image.png
    • 定义自己的服务,继承GreeterImplBase并重写契约中定义的服务sayHello,实现真正的业务逻辑。onNext方法用来返回 helloReply对象给客户端,onCompleted方法用来标明此次RPC调用已结束。

      public class MyService extends GreeterImplBase {
          @Override
          public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
              HelloReply helloReply = HelloReply.newBuilder().setMessage("hello client.").build();
              responseObserver.onNext(helloReply);
              responseObserver.onCompleted();
          }
      }
      
    • 创建好自定义服务后,就可以新建和启动一个服务器,用来接收客户端的连接。
      1. 使用ServerBuilder创建服务器,forPort方法监听端口
      2. 创建MyService的一个实例,并传递给ServerBuilderaddService方法
      3. 调用buildstart启动服务器

      public class MyServer {
      
          public static void main(String[] args) {
              ServerBuilder<?> serverBuilder = ServerBuilder.forPort(8899);
              serverBuilder.addService(new MyService());
              Server server = serverBuilder.build();
              try {
                  server.start();
                  server.awaitTermination();
              } catch (IOException | InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }
      
    • 创建客户端:

      1.创建gRPC channel,将stub与服务器连接:这里使用ManagedChannelBuilder来指定主机和端口

      1. 将创建的channel作为参数,创建stub

      2. 使用stub像调用本地方法一样调用远程服务

        public class MyClient {

         public static void main(String[] args) {
             //使用usePlaintext,否则使用加密连接
             ManagedChannelBuilder<?> channelBuilder = ManagedChannelBuilder.forAddress("localhost", 8899).usePlaintext();
             ManagedChannel channel = channelBuilder.build();
        
             GreeterGrpc.GreeterBlockingStub blockingStub = GreeterGrpc.newBlockingStub(channel);
             HelloWorldProtos.HelloReply helloReply = blockingStub.sayHello(HelloWorldProtos.HelloRequest.newBuilder().setMessage("hello wolrd").build());
             System.out.println(helloReply.getMessage());
         }
        

        }

    注:1. clone仓库后,运行gradle clean build生成build文件夹,并将main目录设置为source root

    main目录设置为Sources
    2. .proto文件默认需要放在src/main/proto下面,否则无法生成代码。另外可以自定义存放目录: 自定义.proto文件的存放目录

    相关文章

      网友评论

          本文标题:gRPC入门-Hello World

          本文链接:https://www.haomeiwen.com/subject/yskqnftx.html