【分布式服务】 RPC 示例(Protocol Buffer)

分布式服务 RPC 示例(Protocol Buffer)

一、Protocol Buffer

20201217132517460

  • mac 安装
brew install protobuf
  1. 存根定义
  • protobuf/service1.proto
syntax = "proto3";

/* 支持导入 */
import "protobuf/test.proto";

/* java 生成的包路径 */
option java_package = "com.bheternal.jhome.rpc.protobuf";
option java_multiple_files = true;
/* java 自定义类名 */
option java_outer_classname = "Service1Protobuf";


/* 请求对象 */
message Service1Request {
  string name = 1;
  int32 size = 2;
  Type type = 3;
  // 支持引用其他对象的对象
  Service1Response.Inner inner = 4;

  // 支持内嵌枚举
  enum Type {
    NAME = 0;
    PROGRAM = 1;

    // 启用支持别名
    option allow_alias = true;
    CYPHER = 1;
    GREMLIN = 1;
  }
}

/* 响应对象 */
message Service1Response {
  string name = 1;
  string desc = 2;
  int64 total = 3;
  Status status = 4;
  Result result = 5;
  Inner inner = 6;
  Error error = 7;

  reserved "other";

  // 支持内嵌对象
  message Inner {
    string test = 1;
  }
}

/* 自定义对象类型 */
message Result {
  int32 code = 1;
  string msg = 2;
  // 字符串数组/列表
  repeated string data = 3;
}

/* 自定义枚举类型 */
enum Status {
  DISABLE = 0;
  ENABLE = 1;
}
  • protobuf/test.proto
syntax = "proto3";

/* 支持引入 google 的对象 */
import "google/protobuf/any.proto";

/* java 生成的包路径 */
option java_package = "com.bheternal.jhome.rpc.protobuf";
option java_multiple_files = true;
/* java 自定义类名 */
option java_outer_classname = "TestProtobuf";

message Error {
  string msg = 1;
  repeated google.protobuf.Any detail = 2;
}
  1. 通过命令将 proto 文件转成 java 文件
# 进入到 java 项目根目录执行
protoc -Isrc/main/resources --java_out=src/main/java protobuf/test.proto
protoc -Isrc/main/resources --java_out=src/main/java protobuf/service1.proto

20201217230304098
20201217232048542

  1. maven 引入 java 包
<!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
<dependency>
  <groupId>com.google.protobuf</groupId>
  <artifactId>protobuf-java</artifactId>
  <version>3.14.0</version>
</dependency>
  1. ProtobufDemo 使用示例
public class ProtobufDemo {

    public static void main(String[] args) throws Exception {
        // 客户端:构造请求对象
        Service1Request request = Service1Request.newBuilder()
                .setName("测试ProtobufDemo请求")
                .setSize(100)
                .setType(Service1Request.Type.CYPHER)
                .setInner(Service1Response.Inner.newBuilder()
                        .setTest("测试其他类的内部类")
                        .build())
                .build();

        // 客户端 -> 服务端 建立链接
        PipedOutputStream os = new PipedOutputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(new PipedInputStream(os)));

        // 客户端:写入到传输流
        request.writeTo(os);
        os.close();

        // 服务端:读取远程数据
        String data = br.lines().collect(Collectors.joining("\n"));
        System.out.printf("Remote data: %s %n%n", data);
        br.close();

        // 服务端:解析远程数据为对象
        Service1Request clientRequest = Service1Request.parseFrom(data.getBytes());
        System.out.printf("Remote clientRequest.name: %s %n%n", clientRequest.getName());
        System.out.printf("Remote clientRequest: %s %n%n", clientRequest);

        // 服务端:制作响应对象
        Service1Response response = Service1Response.newBuilder()
                .setName("测试ProtobufDemo响应")
                .setDesc("描述详情")
                .setTotal(100000000)
                .setStatus(Status.ENABLE)
                .setError(Error.newBuilder()
                        .setMsg("模拟错误")
                        .addDetail(0, Any.newBuilder()
                                .setValue(ByteString.copyFrom(new NullPointerException("模拟空指针异常").getMessage().getBytes()))
                                .build())
                        .build())
                .build();

        // 客户端 <- 服务端 建立链接
        os = new PipedOutputStream();
        br = new BufferedReader(new InputStreamReader(new PipedInputStream(os)));

        // 服务端:写入响应数据
        response.writeTo(os);
        os.close();

        // 客户端:读取远程数据
        data = br.lines().collect(Collectors.joining("\n"));
        System.out.printf("Remote data: %s %n%n", data);
        br.close();

        // 客户端:解析远程数据为对象
        Service1Response serverResponse = Service1Response.parseFrom(data.getBytes());
        System.out.printf("Remote serverResponse.name: %s %n%n", serverResponse.getName());
        System.out.printf("Remote serverResponse.err: %s %n%n", serverResponse.getError().getDetail(0).getValue().toString(Charset.defaultCharset()));
        System.out.printf("Remote serverResponse: %s %n%n", serverResponse);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值