This article focuses on a simple example of gRPC in Java.

preface

We should not only look at the principles and ignore the practice, nor should we focus on the practice and ignore the principle. We should do both!

In the first two articles, “BASIC RPC Series 1: Talking about RPC” and “Basic RPC Series 2: Understanding the Basic Principles and Differences between gRPC and Thrift,” you can get a basic understanding of three important concepts: RPC, gRPC and Thrift. This article will look at the use of gPRC.

GRPC sample

Code: [email protected]: lml200701158 / RPC – study. Git

The project structure

Let’s look at the project structure first:

Generate the protobuf file

helloworld.proto

syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";

package helloworld;

// The greeting 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;
}
Copy the code

You can see that the proto file only defines the format of the input and return values, and the interface to be called. As for the internal implementation of the interface, the file doesn’t care at all.

pom.xml

<? xml version="1.0" encoding="UTF-8"? > <project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>rpc-study</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0. 0</modelVersion>

    <artifactId>grpc-demo</artifactId>

    <dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
            <version>1.14. 0</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.14. 0</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>1.14. 0</version>
        </dependency>
    </dependencies>

    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.5. 0.Final</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.51.</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.51.-1:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.14. 0:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>6</source>
                    <target>6</target>
                </configuration>
            </plugin>

        </plugins>
    </build>
</project>
Copy the code

Protobuf :compile and protobuf:compile- Javanano. When we execute them directly, the file on the left will be generated. GreeterGrpc provides the call interface, and the file function beginning with Hello is mainly to serialize the data, and then process the incoming parameters and return values.

If you want to put the files in target, you can either copy them or use a tool to generate them:

  • Download protoc.exe from github.com/protocolbuf…
  • Download protoc – gen – GRPC plug-in, download address: jcenter.bintray.com/io/grpc/pro…

Server and client

HelloWorldClient.java

public class HelloWorldClient {
    private final ManagedChannel channel;
    private final GreeterGrpc.GreeterBlockingStub blockingStub;
    private static final Logger logger = Logger.getLogger(HelloWorldClient.class.getName());

    public HelloWorldClient(String host,int port){
        channel = ManagedChannelBuilder.forAddress(host,port)
                .usePlaintext(true)
                .build();

        blockingStub = GreeterGrpc.newBlockingStub(channel);
    }


    public void shutdown(a) throws InterruptedException {
        channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
    }

    public  void greet(String name){
        HelloRequest request = HelloRequest.newBuilder().setName(name).build();
        HelloReply response;
        try{
            response = blockingStub.sayHello(request);
        } catch (StatusRuntimeException e)
        {
            logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
            return;
        }
        logger.info("Message from gRPC-Server: "+response.getMessage());
    }

    public static void main(String[] args) throws InterruptedException {
        HelloWorldClient client = new HelloWorldClient("127.0.0.1".50051);
        try{
            String user = "world";
            if (args.length > 0){
                user = args[0];
            }
            client.greet(user);
        }finally{ client.shutdown(); }}}Copy the code

This is too simple. Connect to the service port and call the sayHello() method.

HelloWorldServer.java

public class HelloWorldServer {
    private static final Logger logger = Logger.getLogger(HelloWorldServer.class.getName());

    private int port = 50051;
    private Server server;

    private void start(a) throws IOException {
        server = ServerBuilder.forPort(port)
                .addService(new GreeterImpl())
                .build()
                .start();
        logger.info("Server started, listening on " + port);

        Runtime.getRuntime().addShutdownHook(new Thread() {

            @Override
            public void run(a) {

                System.err.println("*** shutting down gRPC server since JVM is shutting down");
                HelloWorldServer.this.stop();
                System.err.println("*** server shut down"); }}); }private void stop(a) {
        if(server ! =null) { server.shutdown(); }}// Block until the program exits
    private void blockUntilShutdown(a) throws InterruptedException {
        if(server ! =null) { server.awaitTermination(); }}public static void main(String[] args) throws IOException, InterruptedException {
        final HelloWorldServer server = new HelloWorldServer();
        server.start();
        server.blockUntilShutdown();
    }

    // The implementation defines a class that implements the service interface
    private class GreeterImpl extends GreeterGrpc.GreeterImplBase {
        @Override
        public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
            HelloReply reply = HelloReply.newBuilder().setMessage(("Hello " + req.getName())).build();
            responseObserver.onNext(reply);
            responseObserver.onCompleted();
            System.out.println("Message from gRPC-Client:" + req.getName());
            System.out.println("Message Response:"+ reply.getMessage()); }}}Copy the code

SayHello () ¶ sayHello() ¶ sayHello() ¶ sayHello() ¶

Start the service

Start Server first and return the following:

Restart the Client and return the following:

The Server returns the following:

Afterword.

This Demo looks very simple, but I have been working on it for most of the day. At first, I didn’t know that two different plug-ins need to be executed to generate protobuf. I thought that just click on protobuf:compile, but protobuf:compile-javanano also needs to click on it.

I want to manually generate protobuf files by downloading my own plug-ins, but the manual generation is not done, and the automatic generation is not available. After a long time, I found that the problem is the cache. Finally, just do “Invalidate Caches/Restart”.

I applied for the post with the words “no zuo no die”, but this process still needs experience.

Welcome to more like, more articles, please pay attention to the wechat public number “Lou Zai advanced road”, point to pay attention, don’t get lost ~~