项目情况:
springboot: 2.2.2
grpc-spring-boot-starter: 2.6.1.RELEASE
项目目录:
mypro:
- person - grpc服务端
- lib - 公共库
- device - grpc客户端
项目建立可参考:项目建立部分可参考我另一篇随笔的项目建立部分:
https://www.cnblogs.com/SamNicole1809/p/12200875.html
步骤一:引入依赖
我是都在lib模块引入的:
<dependency> <groupId>net.devh</groupId> <artifactId>grpc-spring-boot-starter</artifactId> <version>2.6.1.RELEASE</version> </dependency> <dependency> <groupId>net.devh</groupId> <artifactId>grpc-server-spring-boot-starter</artifactId> <version>2.6.1.RELEASE</version> </dependency> <dependency> <groupId>net.devh</groupId> <artifactId>grpc-client-spring-boot-starter</artifactId> <version>2.6.1.RELEASE</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-stub</artifactId> <version>1.26.0</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-protobuf</artifactId> <version>1.26.0</version> </dependency>
<properties>
<java.version>1.8</java.version>
<os.plugin.version>1.6.2</os.plugin.version>
<grpc.version>1.26.0</grpc.version>
<protoc.version>3.11.0</protoc.version>
<protobuf.plugin.version>0.6.1</protobuf.plugin.version>
<skipTests>true</skipTests>
</properties>
<build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>${os.plugin.version}</version> </extension> </extensions> <plugins> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>${protobuf.plugin.version}</version> <extensions>true</extensions> <configuration> <protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact> <protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot> <outputDirectory>${project.basedir}/src/main/java</outputDirectory> <clearOutputDirectory>false</clearOutputDirectory> <!-- for more https://www.xolstice.org/protobuf-maven-plugin/compile-mojo.html --> </configuration> <executions> <execution> <!-- run mvn compile --> <phase>compile</phase> <goals> <!-- produce OuterClass --> <goal>compile</goal> <!-- produce Grpc class --> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
person模块引入:
<dependency> <groupId>net.devh</groupId> <artifactId>grpc-server-spring-boot-starter</artifactId> <version>2.6.1.RELEASE</version> </dependency>
person的application.yml
grpc:
server:
port: 9898
device模块引入:
<dependency> <groupId>net.devh</groupId> <artifactId>grpc-client-spring-boot-starter</artifactId> <version>2.6.1.RELEASE</version> </dependency>
device的application.yml
grpc: client: person: address: 'static://127.0.0.1:9898' enableKeepAlive: true keepAliveWithoutCalls: true negotiationType: plaintext
步骤二:生成proto文件
在lib的main目录下新建文件夹proto,再在文件夹中新建文件mypro.proto,文件名可随意。
mypro.proto文件内容:
syntax = "proto3"; option java_package = "com.sam.lib"; option java_multiple_files = true; option java_outer_classname = "MyproRpcProto"; service MyproRpcService { rpc getUser (GrpcStringRequest) returns (GrpcStringResponse) {} } message GrpcStringRequest { string str = 1; } message GrpcStringResponse { string str = 1; }
安装完相关依赖后,maven中lib的Plugins目录下找到protobug,依次执行compile和compile-custom
执行时需要下载,下载速度比较慢,第二次就很快了,下载完执行如果出错,多半是proto文件内容的问题。
执行成功后会出现如下文件:
utils是我自己建的,主要是下面那些。
步骤三:给person和device增加lib扫描,使其能够引用lib中的所有文件,lib和自己都要加,person同理。
@SpringBootApplication @ComponentScan({"com.sam.lib.*", "com.sam.device.*"}) public class DeviceApplication { public static void main(String[] args) { SpringApplication.run(DeviceApplication.class, args); } }
步骤四:服务端代码
import com.sam.lib.GrpcStringRequest; import com.sam.lib.GrpcStringResponse; import com.sam.lib.MyproRpcServiceGrpc; import io.grpc.netty.shaded.io.netty.util.internal.StringUtil; import io.grpc.stub.StreamObserver; import net.devh.boot.grpc.server.service.GrpcService; import java.util.UUID; @GrpcService public class PersonGrpcService extends MyproRpcServiceGrpc.MyproRpcServiceImplBase { @Override public void getUser(GrpcStringRequest request, StreamObserver<GrpcStringResponse> responseObserver) { String name = request.getStr(); // 接收请求的内容
// 定义返回的内容 GrpcStringResponse response = GrpcStringResponse.newBuilder().setStr("").build();
// 如果请求正确,返回name和uuid,不正确返回空字符串 if (!StringUtil.isNullOrEmpty(name)) { String result = name + "--" + UUID.randomUUID().toString(); response = GrpcStringResponse.newBuilder().setStr(result).build(); } responseObserver.onNext(response); responseObserver.onCompleted(); } }
步骤五:客户端代码
import com.sam.lib.GrpcStringRequest; import com.sam.lib.GrpcStringResponse; import com.sam.lib.MyproRpcServiceGrpc; import io.grpc.Channel; import net.devh.boot.grpc.client.inject.GrpcClient; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; @Service public class DeviceGrpcService { @GrpcClient("person") // grpc服务的名称 private Channel channel; private MyproRpcServiceGrpc.MyproRpcServiceBlockingStub stub; @PostConstruct public void init() { stub = MyproRpcServiceGrpc.newBlockingStub(channel); } public String getUser(String name) { GrpcStringResponse response = stub.getUser(GrpcStringRequest.newBuilder().setStr(name).build()); return response.getStr(); } }
步骤六:controller测试
@GetMapping("/grpc") public String setGrpc() { String result = deviceGrpcService.getUser("device"); if ("".equals(result)) { return "Result is blank"; } return result; }
至此,grpc调用成功。