proto文件说明和 java中 gRPC初步搭建使用

gRPC 专栏收录该内容
1 篇文章 0 订阅

gRPC

  1. gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持. 中文官网

  1. 正如其他 RPC 系统,gRPC 基于如下思想:定义一个服务, 指定其可以被远程调用的方法及其参数和返回类型。gRPC 默认使用 protocol buffers 作为接口定义语言,来描述服务接口和有效载荷消息结构

1.proto文件

字段类型
double——>java:double
float——>java: float
int32——>java :int [使用可变长度编码。编码负数的效率低 - 如果你的字段可能有负值,请改用 sint32]
int64——>java: long [使用可变长度编码。编码负数的效率低 - 如果你的字段可能有负值,请改用 sint64]
uint32——> java:int [使用可变长度编码]
uint64——> java :int/long [使用可变长度编码]
sint32——> java:int [使用可变长度编码。有符号的 int 值。这些比常规 int32 对负数能更有效地编码]
sint64——> java:long [使用可变长度编码。有符号的 int 值。这些比常规 int64 对负数能更有效地编码]
fixed32——>java:int [总是四个字节。如果值通常大于 228,则比 uint32 更有效。]
fixed64——>java:long [总是八个字节。如果值通常大于 256,则比 uint64 更有效]
sfixed32 ——>java : int [总是四个字节]
sfixed64——>java:long [总是八个字节 ]
bool ——>java :boolean
string ——>java:String [字符串必须始终包含 UTF-8 编码或 7 位 ASCII 文本]
bytes——>java:ByteString [可以包含任意字节序列 ]

  • 其他类型

1.列表 - list

reapeat string  str = 1

​ 2. map

map<string,string>  userMap = 1

​ 3. 实体类型 --message


message User{   

         string  name = 1;

         string  age = 2}

​ 4. 泛型(泛型最终会对应的实体类型也要先在.proto中定义好 ) Any

/*  需要提前导入Any文件*/       
import "google/protobuf/any.proto";     


message User{   

         string  name = 1;

         string  age = 2;

		google.protobuf.Any data = 3;
}
 

2.具体使用

maven 依赖

	   
	   <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-all</artifactId>
            <version>1.12.0</version>
        </dependency>

插件

<plugin>
    <groupId>org.xolstice.maven.plugins</groupId>
    <artifactId>protobuf-maven-plugin</artifactId>
    <version>0.5.0</version>
    <configuration>
        <protocArtifact>
            com.google.protobuf:protoc:3.4.0:exe:${os.detected.classifier}
        </protocArtifact>
        <pluginId>grpc-java</pluginId>
        <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
        <!-- proto 文件路径 -->
        <protoSourceRoot>${project.basedir}/src/main/resources/static/proto</protoSourceRoot>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
                <goal>compile-custom</goal>
            </goals>
        </execution>
    </executions>
</plugin>

proto文件

syntax = "proto3";

import "google/protobuf/any.proto";

option java_multiple_files = true;
//生成的java
option java_package = "com.reagent.service";
option java_outer_classname = "MessageModel";


//生产带有抽象方法的java类
service SendMessage{
     rpc sendMessageWithResult(Msg) returns (RequestResult){}

     rpc sendMessage(Msg) returns (RequestResult){}

}

message Msg {
     string topic = 1;
     string tag = 2;
     string msgbody = 3;
}

message RequestResult {
     string resultCode = 1;
     string resultMsg = 2;
     google.protobuf.Any data = 3;
     enum ResultCode{
          RESULT_CODE_SUCCESS = 0;
          RESULT_CODE_FAIL = 1;
     }
}

message Data{
     string msg = 1;
}


common(通过插件生成的java类和gRPC接口)

​ 1. 实体java类

​ 2. XXXGRpc

gRPC服务端

​ 1. 实现类
​ 通过继承XXXGRpc文件 的XXXImplBase抽象方法重写方法的实现类

@Override
public void sendMessageWithResult(Msg request, StreamObserver<RequestResult> responseObserver){
    com.reagent.common.util.RequestResult result = producer
        .sendMsgWithResult(
        	request.getTopic(), 
        	request.getTag(), 
        	request.getMsgbody());
    //        Data data = Data.newBuilder().setMsg("pretend to return result.getData()").build();
    //封装返回的数据
    RequestResult requestResult = RequestResult.newBuilder()
        //.setData(Any.pack(data))
        .setResultMsg(result.getResultMsg())
        .setResultCode(result.getResultCode()+"")
        .build();

    responseObserver.onNext(requestResult);
    responseObserver.onCompleted();
}

​ 2.服务端

​ 启动服务端,配置端口…

private Server server;

private void start() throws IOException {
    server = ServerBuilder.forPort(port).addService(service).build();
    server.start();
    logger.info("Server has started, listening on " + port);
    Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {

            GRpcServer.this.stop();

        }
    });
}

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

gRPC客户端

​ 1. 客户端
​ 配置服务端地址和端口
​ 编写请求方法(接口) 通过builder封装实体,再通过XXXGRpc文件中的XXXBlockingStub来发送请求

//    @Value("defaultHost")
//    private String host = ;

//    @Value("defaultPort")
//    private int port;
private SendMessageGrpc.SendMessageBlockingStub sendMessageBlockingStub;

public GRpcClient(){
    this(DEFAULT_HOST,DEFAULT_PORT);
}

public GRpcClient(String host, int port) {

    this(ManagedChannelBuilder.forAddress(host,port).usePlaintext(true).build());

}


public GRpcClient(ManagedChannel managedChannel) {
    this.managedChannel = managedChannel;
    this.sendMessageBlockingStub = SendMessageGrpc.newBlockingStub(managedChannel);
}

public RequestResult sendMsgWithResult(String topic, String tag, String messageBody){
    Msg msg = Msg.newBuilder()
        .setTopic(topic)
        .setTag(tag)
        .setMsgbody(messageBody)
        .build();
    RequestResult result = sendMessageBlockingStub
        						.sendMessageWithResult(msg);
    logger.warn("result: { resultCode: "
                +result.getResultCode()
                +", resultMsg: "+result.getResultMsg()
                +", resultData: "+result.getData()+"}");
    return result;
}

ingStub
        						.sendMessageWithResult(msg);
    logger.warn("result: { resultCode: "
                +result.getResultCode()
                +", resultMsg: "+result.getResultMsg()
                +", resultData: "+result.getData()+"}");
    return result;
}
  • 2
    点赞
  • 0
    评论
  • 5
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论
请先登录 后发表评论~
©️2021 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页

打赏作者

color2Rain

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值