grpc是由google推出的高性能的RPC框架,基于http2和protobuf
一、引入grpc相关依赖
<!--grpc-->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.21.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.21.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.21.0</version>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.21.0</version>
</dependency>
</dependency>
二、添加插件
添加的插件作用是将.proto文件编译为java代码。
插件配置中goals中compile表示编译.proto文件为Message对象,compile-custom表示编译.proto文件为gRPC对象。
注意:此插件编译后输出的java代码不在源码目录下,默认位置在打包目录的generated-sources/protobuf/文件夹下
在pom.xml文件下面添加
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.1</version>
<configuration>
<protocArtifact>
com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}
</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>
io.grpc:protoc-gen-grpc-java:1.21.0:exe:${os.detected.classifier}
</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
如果想要输出不同目录,可自定义配置
<properties>
<!-- Message源文件输出目录 -->
<javaOutputDirectory>${project.basedir}/src/main/java-proto</javaOutputDirectory>
<!-- gRPC源文件输出目录 -->
<protocPluginOutputDirectory>
${project.basedir}/src/main/java-grpc
</protocPluginOutputDirectory>
</properties>
三、导入或新建proto相关文件
在main目录下,建一个和java同级的proto文件夹
如果是项目中需要,把那边给的文件放进去即可
在该文件夹下创建一个hello_world.proto文件,把下面代码复制进去
syntax = "proto3";
option java_package = "com.example.grpc";
option java_multiple_files = true;
option java_outer_classname = "HelloWorldProto";
message Greeting {
string name = 1;
}
message HelloResp {
string reply = 1;
}
service HelloWorld {
rpc sayHello (Greeting) returns (HelloResp);
}
说明:
java_package表示生成java代码的包名;
java_multiple_files = true 表示生成多个java文件,若不设置该属性,则只会生成一个java文件;
java_outer_classname表示包含message描述的java文件的类名;
四、生成相关目录及代码
打开maven页面,按顺序双击下图红框
将会生成下面目录
五、编写调试代码
- 实现服务端的sayHello方法
这里实现的是传入名字,然后返回Hello, {name}!
package com.example.grpc;
import io.grpc.stub.StreamObserver;
public class HelloWorldRpcService extends HelloWorldGrpc.HelloWorldImplBase {
@Override
public void sayHello(Greeting request, StreamObserver<HelloResp> responseObserver) {
String name = request.getName();
HelloResp resp = HelloResp.newBuilder()
.setReply("Hello " + name + "!")
.build();
responseObserver.onNext(resp);
responseObserver.onCompleted();
}
}
- 创建grpc的服务端
package com.example.grpc;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import java.io.IOException;
public class GrpcServer {
private Server server;
/**
* @param port 服务端占用的端口
*/
public GrpcServer(int port) {
server = ServerBuilder.forPort(port)
// 将具体实现的服务添加到gRPC服务中
.addService(new HelloWorldRpcService())
.build();
}
public void start() throws IOException {
server.start();
}
public void shutdown() {
server.shutdown();
}
}
六、创建客户端连接
创建客户端连接,调用上面的server服务端接口
package com.example.grpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
public class HelloWorldClient {
private final HelloWorldGrpc.HelloWorldBlockingStub blockingStub;
private static ManagedChannel managedChannel =null;
/**
* @param host gRPC服务的主机名
* @param port gRPC服务的端口
*/
public HelloWorldClient(String host, int port) {
managedChannel = ManagedChannelBuilder.forAddress(host, port)
// 使用非安全机制传输
.usePlaintext()
.build();
blockingStub = HelloWorldGrpc.newBlockingStub(managedChannel);
}
public String sayHello(String name) {
Greeting greeting = Greeting.newBuilder()
.setName(name)
.build();
HelloResp resp = blockingStub.sayHello(greeting);
return resp.getReply();
}
public void shutdown() {
managedChannel.shutdown();
}
}
测试
package com.example.grpc;
public class HelloWorldApp {
public static void main(String[] args) throws Exception {
int port = 8000;
GrpcServer server = new GrpcServer(port);
server.start();
HelloWorldClient client = new HelloWorldClient("localhost", port);
String reply = client.sayHello("hello word");
System.out.println(reply);
// 关闭服务与通道,否则会报错
server.shutdown();
client.shutdown();
}
}
成功的话会输出:hello word