欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Grpc Golang 客户端调用 Java 服务端

程序员文章站 2022-05-18 16:34:02
...

proto protobuf

syntax = "proto3";

// go 生成文件所在包
option go_package = "proto";
option java_multiple_files = true;
// java 生成文件所在包
option java_package = "com.bocloud.autorelease.hello";
// java 生成文件类名称
option java_outer_classname = "HelloProto";
option objc_class_prefix = "HL";

package hello;

service Hello {
  // 接口 1 
  rpc SayHello (HelloRequest) returns (HelloResponse) {}
  // 接口 2
  rpc SayOperation (WatchObject) returns (HelloResponse) {}
}

// 数据结构
message WatchObject{
  ServiceObject service = 1;
  DeployObject  deploy  = 2;
  string        verb    = 3;
}

// 数据结构
message ServiceObject{
  string name = 1;
  string namespace = 2;
  map<string, string> labels = 3;
}

// 数据结构
message DeployObject{
  string name = 1;
  string namespace = 2;
  map<string, string> labels = 3;
}

// 数据结构.
message HelloRequest {
  string name = 1;
}

// 数据结构
message HelloResponse {
  string message = 1;
}

初始化 go 客户端

1:生成代码
需要注意的地方:

  • 需要在 proto 文件目录生成,先安装 protoc 命令
protoc --go_out=plugins=grpc:./ ./hello.proto

2:生成代码以后的目录层级
Grpc Golang 客户端调用 Java 服务端

  • proto 是我的 proto 文件以及生成的文件所在的目录
  • test 是我的测试客户端,client.go 是我调用 java 服务端的文件
  • go.mod go 依赖

3:测试 client.go

package main

import (
	"auth-release/proto"
	"context"
	"google.golang.org/grpc"
	"log"
)

const (
	Address string = "127.0.0.1:50051"
)

func main() {
	// 连接服务器
	conn, err := grpc.Dial(Address, grpc.WithInsecure())
	if err != nil {
		log.Fatalf("net.Connect err: %v", err)
	}

    // 创建客户端
	grpcClient := proto.NewHelloClient(conn)
	req := proto.HelloRequest{Name: "Tom"}

    // 调用 Server
	res, err := grpcClient.SayHello(context.Background(), &req)
	if err != nil {
		log.Fatalf("Call Route err: %v", err)
	}
	// 打印返回值
	log.Println(res)
}

4:go 依赖
差点忘记说,go.mod 中的依赖

	github.com/golang/protobuf v1.4.2
	google.golang.org/grpc v1.28.1
	google.golang.org/protobuf v1.23.0

初始化 java 服务端

1:添加依赖
必须添加下面这些依赖,不然生成之后会出现错误。

        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.23.1</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>1.23.1</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
            <version>1.23.1</version>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
        </dependency>

        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.5.0.Final</version>
            </extension>
        </extensions>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.5.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.23.1:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

2:生成代码
需要注意的地方:

  • proto 文件所在的目录需要与 java、resource 目录等级相同。如下所示,proto 目录就是我 proto 文件的目录
  • 复制完文件之后直接将 target 清理了 mvn clean
    Grpc Golang 客户端调用 Java 服务端
    添加依赖之后,直接 maven clean install 即可
    Grpc Golang 客户端调用 Java 服务端
    为什么生成的目录是这样的?因为早在 porto 文件中已经定义了 java 文件的生成目录,以及生成名称, 下面两行
option java_package = "com.bocloud.autorelease.hello";
option java_outer_classname = "HelloProto";

然后复制这些文件到你项目中
Grpc Golang 客户端调用 Java 服务端
3:添加 server 端

package com.bocloud.autorelease.server;

import com.bocloud.autorelease.hello.*;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;

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

import static io.grpc.stub.ClientCalls.asyncUnaryCall;

public class HelloServer {

    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 HelloIml())  //这里可以添加多个模块
                .build()
                .start();
        System.out.println("Server started, listening on " + port);
        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 {
                    HelloServer.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);
        }
    }

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

    public static void main(String[] args) throws IOException, InterruptedException {
        final HelloServer server = new HelloServer();
        server.start();
        server.blockUntilShutdown();
    }

    private static class HelloIml extends HelloGrpc.HelloImplBase{
        @Override
        public void sayHello(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {
            // super.sayHello(request, responseObserver);
            HelloResponse helloResponse=HelloResponse.newBuilder().setMessage("Hello "+request.getName()+", I'm Java grpc Server").build();
            responseObserver.onNext(helloResponse);
            responseObserver.onCompleted();
        }

        @Override
        public void sayOperation(WatchObject request,
                                 io.grpc.stub.StreamObserver<HelloResponse> responseObserver) {

            System.out.println("Deployment" +"="+ request.getDeploy().toString());
            System.out.println("Service" +"="+ request.getService().toString());
            System.out.println("operation" +"="+ request.getVerb());

            HelloResponse helloResponse=HelloResponse.newBuilder().setMessage("Watch operation"+request.getVerb()+", I've responded").build();
            responseObserver.onNext(helloResponse);
            responseObserver.onCompleted();
        }
    }
}

运行测试

1:启动 server

10:18:37.447 [main] DEBUG io.grpc.netty.shaded.io.netty.buffer.ByteBufUtil - -Dio.netty.allocator.type: pooled
10:18:37.447 [main] DEBUG io.grpc.netty.shaded.io.netty.buffer.ByteBufUtil - -Dio.netty.threadLocalDirectBufferSize: 0
10:18:37.447 [main] DEBUG io.grpc.netty.shaded.io.netty.buffer.ByteBufUtil - -Dio.netty.maxThreadLocalCharBufferSize: 16384
Server started, listening on 50051

启动成功,并且监听在 50051 端口

2:指定 client 调用

2020/09/11 10:21:03 message:"Hello Tom, I'm Java grpc Server"

Process finished with exit code 0

执行成功。上面我写了两个接口,大家可以尝试调用另一个接口试试。

上一篇: 运算符重载

下一篇: 运算符重载