Java On gRpc
在java中使用gRpc需要先安装Protocol Buffters和对应的支持库,Protocol Buffters上文有介绍如何安装,这里介绍支持库的安装
安装支持库
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.llllluuusa</groupId>
<artifactId>gRPC</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- gRPC 核心库 -->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.57.2</version> <!-- 请根据需要选择版本 -->
</dependency>
<!-- gRPC protobuf 库 -->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.57.2</version>
</dependency>
<!-- gRPC 生成的代码库 -->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.57.2</version>
</dependency>
<!-- Protobuf Java 支持库 -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.24.3</version>
</dependency>
</dependencies>
<build>
<extensions>
<!-- Maven protobuf 插件,用于 gRPC 和 protobuf 文件的生成 -->
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.7.0</version>
</extension>
</extensions>
<plugins>
<!-- 用于生成 protobuf 和 gRPC 代码 -->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.24.3:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.57.2:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
生成代码
通过maven将代码生成出来,生成的代码位置于target/generated-sources/protobuf/grpc-java
mvn clean complete
客户端
单一请求客户端
// 连接 gRPC 服务
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8080)
.usePlaintext()
.build();
// 创建 gRPC 客户端存根
服务名Grpc.服务名BlockingStub stub =服务名Grpc.newBlockingStub(channel);
// 为客户端添加拦截器(如果有)
//服务名Grpc服务名BlockingStub stub =服务名Grpc.newBlockingStub(
// ClientInterceptors.intercept(channel, new 拦截器()));
// 创建请求
请求名 request = 请求名.newBuilder()
.setMessage("我是请求消息")
.build();
// 发送请求并获取响应
响应名 response = stub.服务方法名(request);
// 打印服务端的响应
System.out.println("服务端执行结果:" + response.getReply());
// 关闭通道
channel.shutdown();
流式请求客户端
// 创建 gRPC 通道
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8080)
.usePlaintext()
.build();
// 创建存根
服务名Grpc.服务名Stub stub = 服务名Grpc.newStub(channel);
// 为客户端添加拦截器(如果有)
//服务名Grpc服务名BlockingStub stub =服务名Grpc.newBlockingStub(
// ClientInterceptors.intercept(channel, new 拦截器()));
// 创建服务端响应的观察者,若服务端是流式使用改方法
StreamObserver<响应名> responseObserver = new StreamObserver<响应名>() {
@Override
public void onNext(响应名 response) {
// 服务端返回响应时处理
System.out.println("服务端执行结果:" + response.getReply());
}
@Override
public void onError(Throwable t) {
System.out.println("服务端响应异常");
t.printStackTrace();
}
@Override
public void onCompleted() {
// 当服务端完成响应时
System.out.println("服务端响应结束");
}
};
// 创建请求流的观察者,若请求是流式使用该方法
StreamObserver<请求名> requestObserver = stub.服务方法(responseObserver);
// 发送多个请求
requestObserver.onNext(请求名.newBuilder().setMessage("我是请求消息1").build());
requestObserver.onNext(请求名.newBuilder().setMessage("我是请求消息2").build());
requestObserver.onNext(请求名.newBuilder().setMessage("我是请求消息3").build());
// 发送完成请求
requestObserver.onCompleted();
// 关闭通道
channel.shutdown();
服务端
单一响应服务端
public class 服务名Impl extends 服务名Grpc.服务名eImplBase {
@Override
public void 服务方法(请求名 request, StreamObserver<响应名> responseObserver) {
// 获取请求中的消息
String message = request.getMessage();
System.out.println("客户端发送的请求:" + message);
// 创建响应
响应名 response = 响应名.newBuilder()
.setReply("我是响应结果")
.build();
// 将响应发送回客户端
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
流式响应服务端
public class 服务名Impl extends 服务名Grpc.服务名eImplBase {
@Override
public StreamObserver<请求名> 服务方法(final StreamObserver<响应名> responseObserver) {
return new StreamObserver<请求名>() {
@Override
public void onNext(请求名 request) {
// 获取请求中的消息
String message = request.getMessage();
System.out.println("客户端发送的请求:" + message);
// 当收到每个请求时,立即生成响应
响应名 response = 响应名.newBuilder()
.setReply("我是响应结果 " + request.getMessage())
.build();
// 发送响应给客户端
responseObserver.onNext(response);
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
}
@Override
public void onCompleted() {
// 当客户端流结束时,通知响应已完成
responseObserver.onCompleted();
}
};
}
}
拦截器
服务端拦截器允许你在请求被服务方法处理之前或之后进行一些额外的操作。常见的使用场景包括:
- 日志记录
- 认证与授权
- 监控
服务端拦截器
public class XxServerInterceptor implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> call,
Metadata headers,
ServerCallHandler<ReqT, RespT> next) {
// 打印请求信息(可以根据需要记录更多信息)
System.out.println("调用的方法: " + call.getMethodDescriptor().getFullMethodName());
// 继续处理请求,传递到下一个处理器
return next.startCall(call, headers);
}
}
客户端拦截器
public class XxClientInterceptor implements ClientInterceptor {
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
MethodDescriptor<ReqT, RespT> method,
CallOptions callOptions,
Channel next) {
// 打印调用的方法名称
System.out.println("调用的方法: " + method.getFullMethodName());
// 继续处理调用
return next.newCall(method, callOptions);
}
}
启动类
public class StartgRpc {
// 启动 gRPC 服务
public static void main(String[] args) throws IOException, InterruptedException {
Server server = ServerBuilder.forPort(8080)
.addService(new StudyServiceImpl())
.intercept(new 拦截器) // 服务端拦截器
.intercept(new 拦截器2) // 可配置多个拦截器
.build()
.start();
System.out.println("gRpc服务启动...");
// 让服务保持运行
server.awaitTermination();
}
}