GoLang与Java各自生成grpc代码流程介绍

  

GoLang与Java都支持gRPC服务的生成,下面将详细介绍它们各自生成gRPC代码的流程:

GoLang生成gRPC代码的流程

1.准备proto文件

准备好proto文件,它定义了gRPC服务所需要的消息结构和服务接口。

syntax = "proto3";

package greeter;

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

2.使用protoc编译proto文件

使用官方提供的protoc工具,生成Go语言的gRPC代码。

protoc --go_out=plugins=grpc:. greeter.proto

其中,--go_out=plugins=grpc:参数表示生成gRPC代码,并指定输出目录为当前目录。

3.编写服务器代码

编写gRPC服务器代码,实现proto文件中定义的服务接口。

package main

import (
    "context"
    "log"
    "net"

    "google.golang.org/grpc"

    pb "github.com/yourPackageName/yourProtoPackageName"
)

const (
    port = ":50051"
)

type server struct {}

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}

func main() {
    lis, err := net.Listen("tcp", port)
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &server{})
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

4.编写客户端代码

编写Golang gRPC客户端代码,调用proto文件中定义的服务接口。

package main

import (
    "context"
    "log"

    "google.golang.org/grpc"

    pb "github.com/yourPackageName/yourProtoPackageName"
)

const (
    address = "localhost:50051"
)

func main() {
    conn, err := grpc.Dial(address, grpc.WithInsecure())
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()
    c := pb.NewGreeterClient(conn)

    name := "world"
    r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name})
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }
    log.Printf("Greeting: %s", r.Message)
}

Java生成gRPC代码的流程

1.准备proto文件

准备好proto文件,它定义了gRPC服务所需要的消息结构和服务接口。

syntax = "proto3";

package greeter;

option java_package = "com.example.grpc";
option java_outer_classname = "GreeterProto";
option objc_class_prefix = "HLW";

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

2.使用protobuf插件生成Java代码

使用protobuf插件,生成Java语言的gRPC代码。

protoc --plugin=protoc-gen-grpc-java=path/to/protoc-gen-grpc-java --grpc-java_out=path/to/output/directory --proto_path=path/to/proto/files --java_out=path/to/output/directory greeter.proto

其中,--grpc-java_out参数表示生成gRPC Java代码,--proto_path--java_out参数表示proto文件和Java代码的输出目录。

3.编写服务器代码

编写gRPC服务器代码,实现proto文件中定义的服务接口。

package com.example.grpc;

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

public class GreeterServer {
    private int port = 50051;
    private Server server;

    private void start() throws Exception {
        server = ServerBuilder.forPort(port)
            .addService(new GreeterImpl())
            .build()
            .start();
        System.out.println("Server started, listening on " + port);

        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                System.err.println("*** shutting down gRPC server since JVM is shutting down");
                GreeterServer.this.stop();
                System.err.println("*** server shut down");
            }
        });
    }

    private void stop() {
        if (server != null) {
            server.shutdown();
        }
    }

    private void blockUntilShutdown() throws Exception {
        if (server != null) {
            server.awaitTermination();
        }
    }

    public static void main(String[] args) throws Exception {
        final GreeterServer server = new GreeterServer();
        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();
            responseObserver.onNext(reply);
            responseObserver.onCompleted();
        }
    }
}

4.编写客户端代码

编写Java gRPC客户端代码,调用proto文件中定义的服务接口。

package com.example.grpc;

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

import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

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

    private final ManagedChannel channel;
    private final GreeterGrpc.GreeterBlockingStub blockingStub;

    public GreeterClient(String host, int port) {
        channel = ManagedChannelBuilder.forAddress(host, port)
                .usePlaintext(true)
                .build();
        blockingStub = GreeterGrpc.newBlockingStub(channel);
    }

    public void shutdown() 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("Greeting: " + response.getMessage());
    }

    public static void main(String[] args) throws Exception {
        GreeterClient client = new GreeterClient("localhost", 50051);
        try {
            String user = "world";
            client.greet(user);
        } finally {
            client.shutdown();
        }
    }
}

上述示例中,我们演示了使用GoLang与Java各自生成gRPC代码的流程,包括准备proto文件、使用相应的工具编译proto文件生成gRPC代码、编写服务器与客户端代码实现服务调用。

相关文章