java 普通工程中使用GRPC,需要满足以下几点
1. server 服务端
2. client 服务调用端
3. proto文件,用于生成grpc需要的代码
4.相应的Jar包支持
步骤1.
创建java maven工程,使用maven对Jar包进行管理,工程目录如下:
步骤2.
在pom.xml中添加相应的依赖,注意依赖的版本,不同的版本生成的代码可能不致
<dependencies>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.12.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.grpc/grpc-stub -->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.31.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.31.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
<version>1.31.1</version>
</dependency>
</dependencies>
步骤3.
编写proto文件,我这里是在api中编写,因为是学习demo,所以都是放在一起,正常情况下,要分成几个工程。这里要注意proto文件存放的位置
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.cc.grpc.userInfo";
service UserInfoService {
rpc queryUserInfo(UserInfoReq) returns (UserInfoResponse) {}
rpc queryUserInfo2(UserInfoReq) returns (UserInfoResponse) {}
rpc queryUserInfo3(UserStr) returns (UserStr) {}
}
message UserStr{
string str = 1;
}
message UserInfoReq {
string name = 1;
int64 id = 2;
}
message UserInfoResponse {
int32 code = 1;
string msg = 2;
bool success = 3;
message Data {
UserInfo userInfo = 1;
}
Data data = 4;
}
message UserInfo {
int64 id = 1;
string name = 2;
string sex = 3;
string addr = 4;
}
步骤4.
在相应的pom.xml中添加编译依赖,这里需要注意版本(protoc:3.12.0),其它的根据这个进行适配
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.34.1:exe:${os.detected.classifier}</pluginArtifact>
<!--设置grpc生成代码到指定路径-->
<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
<!--生成代码前是否清空目录-->
<clearOutputDirectory>false</clearOutputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- 设置多个源文件夹 -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<!-- 添加主源码目录 -->
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.basedir}/src/main/gen</source>
<source>${project.basedir}/src/main/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
步骤5.
生成GRPC代码,使用ideal,直接在maven操作区,点击compile,如果出现错误,可能需要安装protobuf插件,点击compile之后,会在相应的目录生成代码,目录的设置是根据步骤4,以及proto的设置决定。
步骤6.
编写server端代码
6.1 编写一个类继承UserInfoServiceGrpc.UserInfoServiceImplBase(这里需要引用api的module),用于获取请求数据,继承之后,可以直接实现相应的方法,可实现的方法是由proto生成,如果想增加一个方法,可以修改proto,然后步骤5即可,这些代码都是生成,就直接上图
6.2 编写server主方法,用于启用服务,这里写的比较繁琐,真正有用的只有一行
步骤7.
编写client端代码,这里与server端一样,也需要引用api module
public class ClientMain {
private final UserInfoServiceGrpc.UserInfoServiceBlockingStub userInfoServiceBlockingStub;
private final ManagedChannel managedChannel;
public ClientMain(String ip,int port) {
this.managedChannel = ManagedChannelBuilder.forTarget(ip+":"+port).usePlaintext().build();
this.userInfoServiceBlockingStub = UserInfoServiceGrpc.newBlockingStub(this.managedChannel);
System.out.println("ip : "+ip+" , port : %s" + port);
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
this.managedChannel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
System.err.println("Client shut down.");
}));
}
private void shutdown() throws InterruptedException {
this.managedChannel.shutdown().awaitTermination(5L, TimeUnit.SECONDS);
}
public static void main(String[] args) throws InterruptedException {
ClientMain clientMain = new ClientMain("0.0.0.0",12346);
UserStr userStr = clientMain.userInfoServiceBlockingStub.queryUserInfo3(UserStr.newBuilder().setStr("zhgnsan").build());
System.out.println("userstr ===== > " + userStr.getStr());
clientMain.shutdown();
}
}