gRPC java combat: génère automatiquement du code java basé sur le fichier proto via le plug-in maven

1 Problème: la documentation officielle du gRPC n'est pas assez détaillée

J'ai rencontré un problème lors de l'enquête gRPC java. Selon la documentation officielle, il n'y a aucun moyen d'exécuter l'exemple avec succès en une seule fois.

Au lieu de cela, il a fallu deux jours complets pour parcourir divers documents pour comprendre la relation entre le compilateur proto, maven et gRPC-java.

Fournissez maintenant un exemple de programme gRPC-java de bout en bout dont l'exécution simultanée peut être garantie.

2 Construisez un projet java via maven

version java: 1.8
version gRPC: 1.29.0
partie de la configuration principale de pom.xml

2.1 Dépendances du noyau Pom

<dependency>
  <groupId>io.grpc</groupId>
  <artifactId>grpc-netty-shaded</artifactId>
  <version>1.29.0</version>
</dependency>
<dependency>
  <groupId>io.grpc</groupId>
  <artifactId>grpc-protobuf</artifactId>
  <version>1.29.0</version>
</dependency>
<dependency>
  <groupId>io.grpc</groupId>
  <artifactId>grpc-stub</artifactId>
  <version>1.29.0</version>
</dependency>
<!-- necessary for Java 9+ -->
<!--java 低于 1.8 的版本不需要此依赖-->
<dependency> 
  <groupId>org.apache.tomcat</groupId>
  <artifactId>annotations-api</artifactId>
  <version>6.0.53</version>
  <scope>provided</scope>
</dependency>

2.2 Plugin proto de configuration pom

os-maven-plugin: Ce plugin peut détecter les informations système actuelles
$ {os.detected.classifier}: Cette variable obtient la version du système d'exploitation, par exemple, osx-x86_64

<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.11.0:exe:${
    
    os.detected.classifier}</protocArtifact>
        <pluginId>grpc-java</pluginId>
        <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.29.0:exe:${
    
    os.detected.classifier}</pluginArtifact>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>compile</goal>
            <goal>compile-custom</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

3 Définissez le fichier proto

Placez le fichier helloworld.proto dans le répertoire src / main / proto
Structure d'organisation du code

syntax = "proto3";

option java_generic_services = true;
option java_multiple_files = true;
option java_package = "io.grpc.examples.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;
}

4 Générez du code java basé sur proto via le plugin maven

Le mvn compilecode de commande d' exécution est généré automatiquement.
Le code généré par défaut se trouve dans le répertoire target / generated-sources / protobuf.
Le répertoire grpc-java contient la classe correspondant au service généré, et le répertoire java contient l'objet java correspondant au message généré.

Le chemin où se trouve le code généré par maven

5 gRPC-java, exemple de code côté serveur

Exécutez directement la fonction principale et le serveur commence à fonctionner.

package io.grpc.examples.helloworld;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;

/**
 * @ClassName HelloWorldServer
 * @Description
 * @Author hugo_lei
 * @Date 13/5/20 上午11:09
 */
public class HelloWorldServer {
    
    


    private Server server;

    private void start() throws IOException {
    
    
        /* The port on which the server should run */
        int port = 50051;
        server = ServerBuilder.forPort(port)
                .addService(new GreeterImpl())
                .build()
                .start();
        Runtime.getRuntime().addShutdownHook(new Thread() {
    
    
            @Override
            public void run() {
    
    
                // Use stderr here since the logger may have been reset by its JVM shutdown hook.
                System.err.println("*** shutting down gRPC server since JVM is shutting down");
                try {
    
    
                    HelloWorldServer.this.stop();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace(System.err);
                }
                System.err.println("*** server shut down");
            }
        });
    }

    private void stop() throws InterruptedException {
    
    
        if (server != null) {
    
    
            server.shutdown().awaitTermination(30, TimeUnit.SECONDS);
        }
    }

    /**
     * Await termination on the main thread since the grpc library uses daemon threads.
     */
    private void blockUntilShutdown() throws InterruptedException {
    
    
        if (server != null) {
    
    
            server.awaitTermination();
        }
    }

    /**
     * Main launches the server from the command line.
     */
    public static void main(String[] args) throws IOException, InterruptedException {
    
    
        final HelloWorldServer server = new HelloWorldServer();
        server.start();
        server.blockUntilShutdown();
    }

    static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
    
    

        @Override
        public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
    
    
            HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
            System.out.println("=====server=====");
            System.out.println("server: Hello " + req.getName());
            responseObserver.onNext(reply);
            responseObserver.onCompleted();
        }
    }
}

6 gRPC-java, exemple de code côté client

Chaque fois que la fonction principale est exécutée, le client équivaut à envoyer une requête au serveur.

package io.grpc.examples.helloworld;

import java.util.concurrent.TimeUnit;

import io.grpc.Channel;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;

/**
 * @ClassName HelloWorldClient
 * @Description
 * @Author hugo_lei
 * @Date 13/5/20 上午11:13
 */
public class HelloWorldClient {
    
    

    private final GreeterGrpc.GreeterBlockingStub blockingStub;

    /** Construct client for accessing HelloWorld server using the existing channel. */
    public HelloWorldClient(Channel channel) {
    
    
        // 'channel' here is a Channel, not a ManagedChannel, so it is not this code's responsibility to
        // shut it down.

        // Passing Channels to code makes code easier to test and makes it easier to reuse Channels.
        blockingStub = GreeterGrpc.newBlockingStub(channel);
    }

    /** Say hello to server. */
    public void greet(String name) {
    
    
        HelloRequest request = HelloRequest.newBuilder().setName(name).build();
        HelloReply response;
        try {
    
    
            response = blockingStub.sayHello(request);
        } catch (StatusRuntimeException e) {
    
    
            return;
        }
        System.out.println("Greeting: " + response.getMessage());
    }

    /**
     * Greet server. If provided, the first element of {@code args} is the name to use in the
     * greeting. The second argument is the target server.
     */
    public static void main(String[] args) throws Exception {
    
    
        String user = "hahahahah";
        // Access a service running on the local machine on port 50051
        String target = "localhost:50051";
        // Allow passing in the user and target strings as command line arguments
        if (args.length > 0) {
    
    
            if ("--help".equals(args[0])) {
    
    
                System.err.println("Usage: [name [target]]");
                System.err.println("");
                System.err.println("  name    The name you wish to be greeted by. Defaults to " + user);
                System.err.println("  target  The server to connect to. Defaults to " + target);
                System.exit(1);
            }
            user = args[0];
        }
        if (args.length > 1) {
    
    
            target = args[1];
        }

        // Create a communication channel to the server, known as a Channel. Channels are thread-safe
        // and reusable. It is common to create channels at the beginning of your application and reuse
        // them until the application shuts down.
        ManagedChannel channel = ManagedChannelBuilder.forTarget(target)
                // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
                // needing certificates.
                .usePlaintext()
                .build();
        try {
    
    
            HelloWorldClient client = new HelloWorldClient(channel);
            client.greet(user);
        } finally {
    
    
            // ManagedChannels use resources like threads and TCP connections. To prevent leaking these
            // resources the channel should be shut down when it will no longer be used. If it may be used
            // again leave it running.
            channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
        }
    }
}

7 Exemple de code gRPC-java en cours d'exécution

Insérez la description de l'image ici

8 Référence

  1. grpc-java
  2. os-maven-plugin
  3. protobuf-maven-plugin

Je suppose que tu aimes

Origine blog.csdn.net/hugo_lei/article/details/106098217
conseillé
Classement