gRPC配置及使用
新建maven项目 learning-grpc 并建立几个模块
Maven工程结构
一共四个模块
grpc-interface
用来存放生成的代码
grpc-service
用来实现接口
grpc-server
简单的服务器
grpc-client
简单的客户端
编写protobuf文件
proto文件放到grpc-interface项目的resources/protobuf/目录下并运行插件生成bean和服务接口的代码
syntax = "proto3"; // 协议版本
// 选项配置
option java_package = "top.lilixin.grpc.api";
option java_outer_classname = "RPCDateServiceApi";
option java_multiple_files = true;
// 定义包名
package top.lilixin.grpc.api;
// 服务接口.定义请求参数和相应结果
service RPCDateService {
rpc getDate (RPCDateRequest) returns (RPCDateResponse) {
}
}
// 定义请求体
message RPCDateRequest {
string userName = 1;
}
// 定义相应内容
message RPCDateResponse {
string serverDate = 1;
}
protobuf-maven 插件
配置
在pom.xml中增加
<build>
<extensions>
<!-- 作用: 读取系统类型 -->
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.1</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
<extensions>true</extensions>
<configuration>
<!--protobuf 文件所在位置-->
<protoSourceRoot>${project.basedir}/src/main/resources/protobuf</protoSourceRoot>
<!-- 编译生产目录 -->
<!--<outputDirectory>${project.build.directory}/generated-sources/protobuf/java</outputDirectory>-->
<outputDirectory>${project.build.sourceDirectory}</outputDirectory>
<!--设置是否在生成java文件之前清空outputDirectory的文件,默认值为true,设置为false时也会覆盖同名文件-->
<clearOutputDirectory>false</clearOutputDirectory>
<temporaryProtoFileDirectory>${project.build.directory}/generated-sources/protobuf/java
</temporaryProtoFileDirectory>
<!--更多配置信息可以查看https://www.xolstice.org/protobuf-maven-plugin/compile-mojo.html-->
<protocArtifact>
com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}
</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.2.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
使用
生成的代码在直接在proto文件中定义的包路下面
grpc-interface项目需要引入grpc的包 否则会报错
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-all</artifactId>
<version>1.12.0</version>
</dependency>
实现服务接口
在grpc-service中实现接口 需要引入 grpc-interface依赖
package top.lilixin.grpc.service;
import io.grpc.stub.StreamObserver;
import top.lilixin.grpc.api.RPCDateRequest;
import top.lilixin.grpc.api.RPCDateResponse;
import top.lilixin.grpc.api.RPCDateServiceGrpc;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.logging.Logger;
/**
* @Description 服务实现类
* @Author lilixin
* @Date 2021/1/20 5:32 下午
**/
public class RPCDateServiceImpl extends RPCDateServiceGrpc.RPCDateServiceImplBase{
private static final Logger logger = Logger.getLogger(RPCDateServiceImpl.class.getName());
@Override
public void getDate(RPCDateRequest request, StreamObserver<RPCDateResponse> responseObserver) {
//定义请求结果
RPCDateResponse rpcDateResponse = null;
String userName = request.getUserName();
String response = "hello " + userName + "! today is " + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
logger.info("服务端收到请求 参数="+userName);
//定义响应
try {
rpcDateResponse = RPCDateResponse
.newBuilder()
.setServerDate(response)
.build();
} catch (Exception e) {
responseObserver.onError(e);
}finally {
responseObserver.onNext(rpcDateResponse);
}
responseObserver.onCompleted();
logger.info("服务端处理请求 完成 参数="+userName);
}
}
实现服务端
在grpc-server中 需要引入 grpc-service依赖
package top.lilixin.grpc;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import sun.rmi.runtime.Log;
import top.lilixin.grpc.service.RPCDateServiceImpl;
import java.io.IOException;
import java.util.logging.Logger;
/**
* @Description TODO
* @Author lilixin
* @Date 2021/1/20 5:54 下午
**/
public class GRPCServer {
private static final Logger logger = Logger.getLogger(GRPCServer.class.getName());
private static final int port = 9999;
public static void main(String[] args) {
try {
Server server = ServerBuilder
.forPort(port)
.addService(new RPCDateServiceImpl())
.build().start();
logger.info("GRpc服务端启动成功 port="+port);
server.awaitTermination();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
实现客户端
在grpc-client中 需要引入 grpc-interface依赖
package top.lilixin.grpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import top.lilixin.grpc.api.RPCDateRequest;
import top.lilixin.grpc.api.RPCDateResponse;
import top.lilixin.grpc.api.RPCDateServiceGrpc;
import java.util.logging.Logger;
/**
* @Description grpc 客户端
* @Author lilixin
* @Date 2021/1/20 5:58 下午
**/
public class GRPCClient {
private static final Logger logger = Logger.getLogger(GRPCClient.class.getName());
private static final String host = "127.0.0.1";
private static final int serverPort = 9999;
public static void main(String[] args) {
// 1. 拿到一个通信的channel
ManagedChannel channel = ManagedChannelBuilder
.forAddress(host, serverPort)
.usePlaintext()
.build();
try {
// 2.拿到对象
RPCDateServiceGrpc.RPCDateServiceBlockingStub rpcDateService = RPCDateServiceGrpc.newBlockingStub(channel);
RPCDateRequest rpcDateRequest = RPCDateRequest
.newBuilder()
.setUserName("lilixin")
.build();
// 3. 请求
RPCDateResponse date = rpcDateService.getDate(rpcDateRequest);
// 4. 输出结果
logger.info("响应结果="+date.getServerDate());
}finally {
// 5.关闭channel, 释放资源.
channel.shutdown();
}
}
}
完整项目代码
Last updated
Was this helpful?