Grpc springboot简易食用指南

模块说明

首先定义三个模块,api模块定义接口,生成基于语言的抽象接口和交互对象;serverclient依赖api模块,其中,service提供抽象接口的具体实现,client则利用抽象接口调用service的具体实现。

引入依赖

定义api模块,添加如下依赖

<dependency>
    <groupId>io.grpc</groupId>
    <artifactId>grpc-netty-shaded</artifactId>
    <version>1.42.1</version>
</dependency>
<dependency>
    <groupId>io.grpc</groupId>
    <artifactId>grpc-protobuf</artifactId>
    <version>1.42.1</version>
</dependency>
<dependency>
    <groupId>io.grpc</groupId>
    <artifactId>grpc-stub</artifactId>
    <version>1.42.1</version>
</dependency>

配置插件(参考官方文档)

    <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>
                <extensions>true</extensions>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.17.2:exe:${os.detected.classifier}
                    </protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.42.1:exe:${os.detected.classifier}
                    </pluginArtifact>
                    <!--默认值-->
                    <protoSourceRoot>src/main/proto</protoSourceRoot>
                    <!--默认值-->
                    <!--<outputDirectory>${project.build.directory}/generated-sources/protobuf/java</outputDirectory>-->
                    <outputDirectory>src/main/java</outputDirectory>
                    <!--设置是否在生成java文件之前清空outputDirectory的文件,默认值为true,设置为false时也会覆盖同名文件-->
                    <clearOutputDirectory>false</clearOutputDirectory>
                    <!--更多配置信息可以查看https://www.xolstice.org/protobuf-maven-plugin/compile-mojo.html-->
                </configuration>
                <executions>
                    <execution>
                        <!--在执行mvn compile的时候会执行以下操作-->
                        <phase>compile</phase>
                        <goals>
                            <!--生成OuterClass类-->
                            <goal>compile</goal>
                            <!--生成Grpc类-->
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

定义服务

api模块main目录下新建proto包用来存放proto文件,定义接口相关内容

例如以下:

syntax = "proto3";
​
//Java文件生成路径
option java_package = "com.example.grpc.api";
​
//默认等于proto文件名
option java_outer_classname = "HelloGrpcProto";
​
//定义服务请求的实体传参
message User {
    string name = 1;
}
​
//定义服务响应实体
message HelloMessage {
    string msg = 1;
}
​
service Hello {
    rpc SayHello(User) returns (HelloMessage);
}

生成服务

然后执行mvn install命令,生成rpc文件:

接下来说一下这2个文件:

HelloGrpc类包含自定义服务生成的stubimplbase等:

HelloGrpcProto包含定义的message生成的类:

服务端使用

作为服务端,引入前面定义的api模块

<dependency>
    <groupId>com.example</groupId>
    <artifactId>grpc-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

服务的具体逻辑需要继承HelloImplBase ,该抽象类包含自定义的服务里的方法,实现该方法的逻辑即可:

@Slf4j
@Component
public class GrpcServiceDemo extends HelloGrpc.HelloImplBase {
​
    @Override
    public void sayHello(HelloGrpcProto.User request, StreamObserver<HelloGrpcProto.HelloMessage> responseObserver) {
        final HelloGrpcProto.HelloMessage message = HelloGrpcProto.HelloMessage
                .newBuilder().setMsg("hello " + request.getName()).build();
        log.info("receive from client: {}", request);
        responseObserver.onNext(message);
        responseObserver.onCompleted();
    }
}

HelloMessage使用newBuilder进行构建,然后使用onNext方法发送消息,onCompleted通知流完成消息发送

启动服务,绑定端口和服务,这里通过Autowired注入定义好的服务,然后调用addService方法绑定服务

    @Autowired
    private GrpcServiceDemo serviceDemo;
​
    @PostConstruct
    public void server() {
        try {
            ServerBuilder.forPort(6666).addService(serviceDemo).build().start();
            log.info("server start at 6666....");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

客户端使用

客户端同样引入api模块,然后构建channel,并绑定到stub,通过stub调用api定义sayHello的方法向服务器发送消息,然后打印服务器返回的消息:

public void client() {
    final ManagedChannel channel = ManagedChannelBuilder
            .forAddress("localhost", 6666).usePlaintext().build();
    final HelloGrpc.HelloBlockingStub stub = HelloGrpc.newBlockingStub(channel);
    final HelloGrpcProto.User user = HelloGrpcProto.User.newBuilder().setName("xxx").build();
    final HelloGrpcProto.HelloMessage message = stub.sayHello(user);
    log.info("response from server: {}", message);
}

启动客户端,调用client方法就可以打印出服务器的返回信息了。

以上,是本人对grpc结合springboot的一个思路,希望对大家有帮助。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值