一.通过maven导入所需jar包
<!--grpc服务-->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.28.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.28.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.28.0</version>
</dependency>
二.定义proto文件
实例:
syntax = "proto3";
package com.csdn;
option java_multiple_files = true;
message GrpcRequest {
string msg=1;
}
message GrpcResponse {
string returninfo = 1;
}
service grpcService {
rpc greet(GrpcRequest) returns (GrpcResponse);
}
相关语法:gRPC之proto语法 - 简书
三.根据proto生成代码,这里介绍两种方式
第一种利用idea的protobuf插件来生成代码,配置如下:
<!--Probuff工具-->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<!--suppress UnresolvedMavenProperty -->
<protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<!--suppress UnresolvedMavenProperty -->
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.30.2:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
</plugin>
此处注意,mac m1芯片执行会报错 ,因为protobuf暂不支持m1芯片,推荐两种解决方案:
1.将os.detected.classifier设置为x86的结构
<properties>
<os.detected.classifier>osx-x86_64</os.detected.classifier>
</properties>
注意查看自己的本地仓库,是否获取到正确的版本
我在测试时,就未获取到这个文件,导致生成不了service代码,只能手动下载后使用指令去生成代码
2.去github上获取源码,重新编译,具体操作详见:Mac M1(Apple Silicon) 安装 protobuf 2.5.0 - 简书
第二种是自己下载对应的jar包,通过命令手动生成,具体操作如下:
windows环境操作:
1.将protoc-3.17.3-windows-x86_64和protoc-gen-grpc-java-1.30.2-windows-x86_64两个文件下载到d盘,并新建test目录用于生成代码
目录结构如下:
---D:
-------protoc-3.17.3-windows-x86_64
-------protoc-gen-grpc-java-1.30.2-windows-x86_64
-------hellogrpc.proto
-------test
2.在d盘目录下打开终端
3.生成model代码
D:\protoc-3.17.3-windows-x86_64.exe --proto_path=D:\ --java_out=D:\test hellogrpc.proto
4.生成service代码
D:\protoc-3.17.3-windows-x86_64.exe --plugin=protoc-gen-grpc-java=D:\protoc-gen-grpc-java-1.30.2-windows-x86_64.exe --proto_path=D:\ --grpc-java_out=D:\test hellogrpc.proto
参数说明
D:\protoc-3.17.3-windows-x86_64.exe //protoc命令所在路径
--plugin=protoc-gen-grpc-java=*** //使用插件并指定路径
--proto_path=* //需要扫描的proto所在目录
--grpc-java_out=* //生成的java代码路径
hellogrpc.proto //proto的名称
参考文章:protobuf java service_【java】protoc不生成.proto中的service,只生成model相关类,求助。..._weixin_39807954的博客-CSDN博客
mac环境下:
1.安装protoc
brew install protobuf
2.mac环境下无法直接调用exe文件,需要自己获取源码编译生成protoc-gen-grpc-java文件
//获取grpc-java源码
git clone https://github.com/grpc/grpc-java.git
//切换分支
git checkout git checkout v1.4.x
//进入grpc-java目录编译
./gradlew build
3.编译产生的文件路径为compiler/build/exe/java_plugin/protoc-gen-grpc-java,也可以直接下载mac版本的protoc-gen-grpc-java.exe插件
4.生成model代码
protoc --proto_path=proto所在目录
--java_out=生成的代码所在目录
proto文件名
5.生成service代码,注意需要先给下载的protoc-gen-grpc-java.exe授权,如果不授权可能会报错program not found or is not executable:
/Users/dao/Downloads/protoc-gen-grpc-java-1.4.0-osx-x86_64.exe: program not found or is not executable
Please specify a program using absolute path or make sure the program is available in your PATH system variable
授权后,可以正常生成service代码,授权代码 chmod 777 protoc-gen-grpc-java-1.4.0-osx-x86_64.exe
protoc
--plugin=protoc-gen-grpc-java=*** //使用插件并指定路径(刚才编译好的文件路径,或者下载的插件地址)
--proto_path=* //需要扫描的proto所在目录
--grpc-java_out=* //生成的java代码路径
hellogrpc.proto //proto的名称
四.服务端代码
package test;
import com.csdn.GrpcRequest;
import com.csdn.GrpcResponse;
import com.csdn.grpcServiceGrpc;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import java.io.IOException;
public class GrpcServer {
private int port = 50051;
private Server server;
private void start() throws IOException {
server = ServerBuilder.forPort(port)
.addService(new grpcImpl())
.build()
.start();
//_log.info("Server started, listening on "+ port);
Runtime.getRuntime().addShutdownHook(new Thread(){
@Override
public void run(){
System.err.println("*** shutting down gRPC server since JVM is shutting down");
GrpcServer.this.stop();
System.err.println("*** server shut down");
}
});
}
private void stop(){
if (server != null){
server.shutdown();
}
}
// block 一直到退出程序
private void blockUntilShutdown() throws InterruptedException {
if (server != null){
server.awaitTermination();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
final GrpcServer server = new GrpcServer();
server.start();
server.blockUntilShutdown();
}
// 实现 定义一个实现服务接口的类
private class grpcImpl extends grpcServiceGrpc.grpcServiceImplBase {
@Override
public void greet(GrpcRequest req, StreamObserver<GrpcResponse> responseObserver){
GrpcResponse response = GrpcResponse.newBuilder().setReturninfo("info").build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
}
五.客户端代码
package test;
import com.csdn.GrpcRequest;
import com.csdn.GrpcResponse;
import com.csdn.grpcServiceGrpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import java.util.concurrent.TimeUnit;
public class GrpcClient {
private final ManagedChannel channel;
public final grpcServiceGrpc.grpcServiceBlockingStub blockingStub;
public GrpcClient(String host, int port) {
channel = ManagedChannelBuilder.forAddress(host, port)
.usePlaintext()
.build();
blockingStub = grpcServiceGrpc.newBlockingStub(channel);
}
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
public static void main(String[] args) throws InterruptedException {
try {
GrpcClient client = new GrpcClient("127.0.0.1", 50051);
//封装请求体
GrpcRequest request =
GrpcRequest.newBuilder().setMsg("").build();
GrpcResponse response;
try {
//响应体
response = client.blockingStub.greet(request);
} catch (Exception e) {
e.printStackTrace();
}finally {
client.shutdown();
}
} catch (Exception e){
e.printStackTrace();
}
}
}