您好,登錄后才能下訂單哦!
項目使用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);
}
}
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。