項目情況:
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調用成功。