使用Grpc+maven定義接口、發布服務、調用服務
阿新 • • 發佈:2018-01-09
snapshot 接口 路徑 exception fin returns 對象 1.4.1 pri
一、pom.xml配置
服務端輸出日誌:
客戶端輸出日誌:
項目使用maven構建,執行mvn compile 命令後,proto文件自動生成java文件,這個功能需要依賴相關編譯插件。
一、pom.xml配置
<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.test.grpcTest</groupId> <artifactId>grpc-api</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging>`` <name>grpc-api</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- 添加grpc相關依賴包 --> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-netty</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-protobuf</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-stub</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-all</artifactId> <version>0.13.2</version> </dependency> </dependencies> <!-- proto自動生成java文件所需的編譯插件 --> <build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.4.1.Final</version> </extension> </extensions> <plugins> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.5.0</version> <configuration> <protocArtifact>com.google.protobuf:protoc:3.0.0:exe:${os.detected.classifier}</protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.0:exe:${os.detected.classifier}</pluginArtifact> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
二、proto文檔(IDL文檔)編輯和編譯成java文件
//指定proto3格式 syntax = "proto3"; //一些生成代碼的設置 option java_multiple_files = false;//以非外部類模式生成 option java_package = "com.test.grpcTest.grpc_api";//所在包名 option java_outer_classname = "Grpc";//最外層類名稱 message UnaryRequest{ string serviceName = 1; string methodName = 2; bytes data = 3; string request_id = 4;//參數默認都為可選,如果沒有賦值,那麽接口中不會出現該參數,不會默認為null之類的 } message UnaryResponse{ string serviceName = 1; string methodName = 2; bytes data = 3; string request_id = 4; } service GrpcService{ // 一對一服務請求 rpc SendUnaryRequest(UnaryRequest) returns(UnaryResponse); }
proto文件編輯好後,在項目根目錄下執行 **mvn compile** 進行編譯 。
如果使用maven編譯proto文件,那麽需要默認將proto文件放在 /src/main/proto/ 路徑下。
編譯後生成的java文件在 target/generated-sources/ 路徑下。
將 java 文件拷貝到 /src/main/java/ 路徑下。
項目文件結構如下:
三、服務端代碼
在 /src/main/java/ 路徑下新建目錄 /server,存放服務端代碼。
package com.test.grpcTest.grpc_api.server; import com.test.grpcTest.grpc_api.GrpcServiceGrpc; import com.test.grpcTest.grpc_api.UnaryRequest; import com.test.grpcTest.grpc_api.UnaryResponse; import com.google.protobuf.ByteString; import io.grpc.Server; import io.grpc.ServerBuilder; import io.grpc.stub.StreamObserver; import java.io.IOException; //Grpc服務器對象 public class GrpcServer { private int port = 50051;//grpc服務端口 private Server server;//grpc server public static void main(String[] args) throws IOException,InterruptedException { final GrpcServer server = new GrpcServer(); server.start(); server.blockUntilShutdown(); } private void start() throws IOException { //指定grpc服務器端口、接口服務對象,啟動grpc服務器 server = ServerBuilder.forPort(port).addService(new GreeterImpl()) .build().start(); System.out.println("service start..."); //添加停機邏輯 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 blockUntilShutdown() throws InterruptedException { if (server != null) { server.awaitTermination(); } } private void stop() { if (server != null) { server.shutdown(); } } //內部類,繼承抽象類 GrpcServiceGrpc.GrpcServiceImplBase, //並重寫服務方法 sendUnaryRequest private class GreeterImpl extends GrpcServiceGrpc.GrpcServiceImplBase { //UnaryRequest 客戶端請求參數, //StreamObserver<UnaryResponse> 返回給客戶端的封裝參數 public void sendUnaryRequest(UnaryRequest request,StreamObserver<UnaryResponse> responseObserver) { ByteString message = request.getData(); System.out.println("server, serviceName:" + request.getServiceName() + "; methodName:" + request.getMethodName()+"; datas:"+new String(message.toByteArray())); UnaryResponse.Builder builder = UnaryResponse.newBuilder(); builder.setServiceName("GrpcServiceResponse").setMethodName("sendUnaryResponse"); responseObserver.onNext(builder.build()); responseObserver.onCompleted(); } } }
服務端輸出日誌:
四、客戶端代碼
package com.test.grpcTest.grpc_api.client;
import java.util.concurrent.TimeUnit;
import com.test.grpcTest.grpc_api.GrpcServiceGrpc;
import com.test.grpcTest.grpc_api.UnaryRequest;
import com.test.grpcTest.grpc_api.UnaryResponse;
import com.google.protobuf.ByteString;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
//grpc客戶端類
public class GrpcClient {
private final ManagedChannel channel;//客戶端與服務器的通信channel
private final GrpcServiceGrpc.GrpcServiceBlockingStub blockStub;//阻塞式客戶端存根節點
public GrpcClient(String host, int port) {
channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext(true).build();//指定grpc服務器地址和端口初始化通信channel
blockStub = GrpcServiceGrpc.newBlockingStub(channel);//根據通信channel初始化客戶端存根節點
}
public void shutdown() throws InterruptedException{
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
//客戶端方法
public void sayHello(String str){
//封裝請求參數
UnaryRequest request = UnaryRequest.newBuilder() .setServiceName("GrpcServiceRequest").setMethodName("sendUnaryRequest").setData(ByteString.copyFrom(str.getBytes()))
.build();
//客戶端存根節點調用grpc服務接口,傳遞請求參數
UnaryResponse response = blockStub.sendUnaryRequest(request);
System.out.println("client, serviceName:"+response.getServiceName()+"; methodName:"+response.getMethodName());
}
public static void main(String[] args) throws InterruptedException{
//初始化grpc客戶端對象
GrpcClient client = new GrpcClient("127.0.0.1",50051);
for(int i=0; i<5; i++){
client.sayHello("client word:"+ i);
Thread.sleep(3000);
}
}
}
客戶端輸出日誌:
使用Grpc+maven定義接口、發布服務、調用服務