grpc是谷歌的一种高性能、开源的通用型RPC框架;支持多达十几种常用语言,它的原理是通过 IDL(Interface Definition Language)文件定义服务接口的参数和返回值类型,然后通过代码生成程序生成服务端和客户端的具体实现代码,这样在 gRPC 里,客户端应用可以像调用本地对象一样调用另一台服务器上对应的方法。
syntax
用来指定protobuf的版本
java_multiple_files
是否多个文件
服务类型
简单rpc:就是一般的rpc调用,一个请求对象对应一个返回对象
proto语法:rpc simpleHello(Person) returns (Result) {}
服务端流式rpc:一个请求对象,服务端可以传回多个结果对象
proto语法:rpc serverStreamHello(Person) returns (stream Result) {}
客户端流式rpc:客户端传入多个请求对象,服务端返回一个响应结果
proto语法:rpc clientStreamHello(stream Person) returns (Result) {}
双向流式rpc:结合客户端流式rpc和服务端流式rpc,可以传入多个对象,返回多个响应对象
proto语法:rpc biStreamHello(stream Person) returns (stream Result) {}
常用的调用方式
1)DialogServiceBlockingStub(阻塞,类似http,一个请求,一个响应)
2)DialogServiceStub(异步调用)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.7.6version>
<relativePath/>
parent>
<groupId>com.gzgroupId>
<artifactId>springboot_grpcartifactId>
<version>1.0.0-SNAPSHOTversion>
<name>springboot_grpcname>
<properties>
<java.version>1.8java.version>
<grpc-client.version>2.10.1.RELEASEgrpc-client.version>
<grpc-server.version>2.10.1.RELEASEgrpc-server.version>
properties>
<packaging>pompackaging>
<modules>
<module>grpc_clientmodule>
<module>grpc_servermodule>
<module>grpc_libmodule>
modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>net.devhgroupId>
<artifactId>grpc-client-spring-boot-starterartifactId>
<version>${grpc-client.version}version>
dependency>
<dependency>
<groupId>net.devhgroupId>
<artifactId>grpc-server-spring-boot-starterartifactId>
<version>${grpc-server.version}version>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.gzgroupId>
<artifactId>springboot_grpcartifactId>
<version>1.0.0-SNAPSHOTversion>
parent>
<groupId>com.gzgroupId>
<artifactId>grpc_clientartifactId>
<version>1.0.0-SNAPSHOTversion>
<name>grpc_clientname>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>net.devhgroupId>
<artifactId>grpc-client-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>com.gzgroupId>
<artifactId>grpc_libartifactId>
<version>1.0.0-SNAPSHOTversion>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.gzgroupId>
<artifactId>springboot_grpcartifactId>
<version>1.0.0-SNAPSHOTversion>
parent>
<groupId>com.gzgroupId>
<artifactId>grpc_serverartifactId>
<version>1.0.0-SNAPSHOTversion>
<name>grpc_servername>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>net.devhgroupId>
<artifactId>grpc-server-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>com.gzgroupId>
<artifactId>grpc_libartifactId>
<version>1.0.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.gzgroupId>
<artifactId>springboot_grpcartifactId>
<version>1.0.0-SNAPSHOTversion>
parent>
<groupId>com.gzgroupId>
<artifactId>grpc_libartifactId>
<version>1.0.0-SNAPSHOTversion>
<name>grpc_libname>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
<dubbo.protobuf.verion>2.7.14dubbo.protobuf.verion>
<dubbo.compiler.version>0.0.2dubbo.compiler.version>
<grpc.version>1.6.1grpc.version>
<protobuf.version>3.3.0protobuf.version>
<protobuf.format.version>1.2protobuf.format.version>
properties>
<dependencies>
<dependency>
<groupId>net.devhgroupId>
<artifactId>grpc-server-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>net.devhgroupId>
<artifactId>grpc-client-spring-boot-starterartifactId>
dependency>
dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.mavengroupId>
<artifactId>os-maven-pluginartifactId>
<version>1.6.2version>
extension>
extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.pluginsgroupId>
<artifactId>protobuf-maven-pluginartifactId>
<version>0.5.0version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}protocArtifact>
<pluginId>grpc-javapluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}pluginArtifact>
<outputDirectory>src/main/javaoutputDirectory>
<clearOutputDirectory>falseclearOutputDirectory>
configuration>
<executions>
<execution>
<goals>
<goal>compilegoal>
<goal>compile-customgoal>
goals>
execution>
executions>
plugin>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
syntax = "proto3";
option java_multiple_files = false;
option java_package = "com.gz.grpc_lib.protobuf";
option java_outer_classname="HelloServiceProto";
service HelloService {
rpc SayHello (HelloRequest) returns (HelloReply) {}
rpc SayHelloBothStream (stream SteamRequest) returns (stream SteamReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
message SteamRequest {
string name = 1;
}
message SteamReply {
string message = 1;
}
grpc:
server:
port: 9999
spring:
application:
name: grpc-server
server:
port: 8888
package com.gz.grpc_server.service.grpc;
import com.gz.grpc_lib.protobuf.HelloServiceGrpc;
import com.gz.grpc_lib.protobuf.HelloServiceProto;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;
/**
* @author GuoZhong
* @description
* @date 2022/12/9 10:34
*/
@GrpcService
@Slf4j
public class UserInfoServiceImpl extends HelloServiceGrpc.HelloServiceImplBase {
@Override
public void sayHello(HelloServiceProto.HelloRequest request, StreamObserver<HelloServiceProto.HelloReply> responseObserver) {
String name = request.getName();
//构建响应值
HelloServiceProto.HelloReply.Builder response=HelloServiceProto.HelloReply.newBuilder();
response.setMessage("hello every one :"+name);
responseObserver.onNext(response.build());
responseObserver.onCompleted();
}
@Override
public StreamObserver<HelloServiceProto.SteamRequest> sayHelloBothStream(StreamObserver<HelloServiceProto.SteamReply> responseObserver) {
return new StreamObserver<HelloServiceProto.SteamRequest>() {
@Override
public void onNext(HelloServiceProto.SteamRequest steamRequest) {
log.info("正在处理");
responseObserver.onNext(HelloServiceProto.SteamReply.newBuilder()
.setMessage(steamRequest.getName())
.build());
}
@Override
public void onError(Throwable throwable) {
log.info("异常",throwable);
}
@Override
public void onCompleted() {
log.info("完成");
responseObserver.onCompleted();
}
};
}
}
grpc:
client:
grpc-server:
address: static://localhost:9999
enableKeepAlive: true
keepAliveWithoutCalls: true
negotiationType: plaintext
spring:
application:
name: grpc-client
server:
port: 8891
package com.gz.grpc_client.controller;
import com.gz.grpc_lib.protobuf.HelloServiceGrpc;
import com.gz.grpc_lib.protobuf.HelloServiceProto;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.ExecutionException;
/**
* @author GuoZhong
* @description
* @date 2022/12/9 11:03
*/
@RestController
@RequestMapping("/test")
public class HelloController {
@GrpcClient("grpc-server")
HelloServiceGrpc.HelloServiceFutureStub helloServiceFutureStub;
@GrpcClient("grpc-server")
HelloServiceGrpc.HelloServiceStub helloServiceStub;
@GetMapping("hello")
public String hello(@PathVariable String name) throws ExecutionException, InterruptedException {
String str=helloServiceFutureStub.sayHello(HelloServiceProto.HelloRequest.newBuilder().setName(name).build()).get().getMessage();
return str;
}
@GetMapping("moreStream")
public void moreStream( ) {
//接受服务端消息
StreamObserver<DialogServiceProto.MoreInvokeDlgStreamResponse> responseObserver =
new StreamObserver<DialogServiceProto.MoreInvokeDlgStreamResponse>() {
@Override
public void onNext(DialogServiceProto.MoreInvokeDlgStreamResponse moreInvokeDlgStreamReply) {
log.info("客户接收信息:{}",moreInvokeDlgStreamReply.getMsg());
}
@Override
public void onError(Throwable throwable) {
log.info("异常", throwable);
}
@Override
public void onCompleted() {
log.info("完成");
}
};
//发送服务端口消息
StreamObserver<DialogServiceProto.MoreInvokeDlgStreamRequest> requestObserver = dialogServiceStub
.moreInvokeDlgStream(responseObserver);
for(int i=1; i <= 10; i++){
// 发送一笔数据到服务端
requestObserver.onNext(DialogServiceProto.MoreInvokeDlgStreamRequest.newBuilder()
.setUuid("测试"+i)
.build());
log.info("客户端发送数据:{}","测试"+i);
}
}
}