您好,登錄后才能下訂單哦!
本文介紹在Java中使用gRPC的過程。一般來說,主要包含以下的三個步驟
1)在.proto文件中定義提供的服務
2)使用protocol buffer編譯器編譯文件
3)使用gRPC API來創(chuàng)建服務端和客戶端,并進行調用。
1)Protocol Buffers
結構化數據序列化機制
https://github.com/protocolbuffers/protobuf/releases
使用示例:
protoc --java_out=./ *.proto
2)protoc-gen-grpc-java
用于生成RPC通信代碼
http://jcenter.bintray.com/io/grpc/protoc-gen-grpc-java/
使用示例【使用Protobuf-Plugin機制】:
protoc --plugin=protoc-gen-grpc-java=protoc-gen-grpc-java-1.19.0-windows-x86_64.exe --grpc-java_out=./ *.proto
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<protobuf.version>3.7.0</protobuf.version>
<grpc.version>1.19.0</grpc.version>
</properties>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<!-- 確保運行時的版本號與protoc的版本號匹配(或更新) -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf.version}</version>
</dependency>
<!-- 如果您想使用像JsonFormat這樣的特性 ,則添加以下依賴-->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>${protobuf.version}</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<!-- 該插件的說明參考 https://github.com/trustin/os-maven-plugin -->
<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.6.1</version>
<configuration>
<!-- proto文件的所在路徑 -->
<!-- <protoSourceRoot>${project.basedir}/src/main/resources/proto</protoSourceRoot> -->
<!-- 編譯后java文件的輸出路徑,默認為${project.build.directory}/generated-sources/protobuf/java -->
<!--<outputDirectory> ${project.build.directory}/generated-sources/protobuf/java</outputDirectory> -->
<!-- 制定protoc編譯器路徑 -->
<!-- <protocExecutable></protocExecutable> -->
<!-- 定義生成的java文件輸出路徑 -->
<!--<outputDirectory>${project.build.sourceDirectory}</outputDirectory> -->
<!--設置是否在生成java文件之前清空outputDirectory的文件,默認值為true,設置為false時也會覆蓋同名文件 -->
<clearOutputDirectory>false</clearOutputDirectory>
<protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
默認情況下,該插件會查找 src/main/proto路徑下的proto文件。該在路徑下的任何子文件夾都會作為proto文件中使用的包路徑。
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.ultrapower.ioss.proto";
option java_outer_classname = "HarLogProto";
package com.ultrapower.grpc.har;
message HarLogResovleRequest{
string url = 1 ;
string file_name = 2;
string file_dir = 3;
string context = 4;
}
message HarLogResovleResponse{
int32 code = 1 ;
}
service HarLogService{
rpc ResovleHarLog(HarLogResovleRequest) returns (HarLogResovleResponse);
rpc BatchResovleHarLog(HarLogResovleRequest) returns (HarLogResovleResponse);
}
mvn protobuf:compile
或
mvn compile
在target\generated-sources\protobuf下會生成以下兩個文件夾
其中java文件夾下面包含了我們定義的message,而grpc-java下存放的是服務端和客戶端都要使用的service。
基于上面的proto文件,生成了兩個java文件
1,HarLogServiceGrpc.java 位于grpc-java下
2,HarLogProto.java等其他文件位于java下
package com.ultrapower.ioss.proto;
public class HarLogServiceImpl extends HarLogServiceGrpc.HarLogServiceImplBase {
@Override
public void resovleHarLog(com.ultrapower.ioss.proto.HarLogResovleRequest request,
io.grpc.stub.StreamObserver<com.ultrapower.ioss.proto.HarLogResovleResponse> responseObserver) {
System.out.println(request.getUrl());
System.out.println(request.getFileName());
System.out.println(request.getFileDir());
System.out.println(request.getContext());
responseObserver.onNext(HarLogResovleResponse.newBuilder().setCode(200).build());
responseObserver.onCompleted();
}
@Override
public void batchResovleHarLog(com.ultrapower.ioss.proto.HarLogResovleRequest request,
io.grpc.stub.StreamObserver<com.ultrapower.ioss.proto.HarLogResovleResponse> responseObserver) {
responseObserver.onNext(HarLogResovleResponse.newBuilder().setCode(200).build());
responseObserver.onCompleted();
}
}
package com.ultrapower.ioss.proto;
import java.io.IOException;
import io.grpc.Server;
import io.grpc.ServerBuilder;
public class RpcServerApp {
private Server server;
private int port = 50051;
public void start() throws IOException {
server = ServerBuilder.forPort(port)
.addService(new HarLogServiceImpl())
.build()
.start();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
RpcServerApp.this.stop();
}
});
}
private void stop() {
if (server != null) {
server.shutdown();
}
}
private void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
public static void main(String[] args) throws Exception {
final RpcServerApp server = new RpcServerApp();
server.start();
server.blockUntilShutdown();
}
}
cnpm install --save grpc-tools
cnpm install --save google-protobuf
cnpm install --save grpc
cnpm install --save @grpc/proto-loader
cnpm install --save @grpc/grpc-js
var grpc = require('grpc');
var PROTO_PATH = __dirname + '/../grpc/protos/HarLog.proto';
var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
var protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
//protoDescriptor + "文件中定義的package"
var harlog = protoDescriptor.com.ultrapower.grpc.har;
/*
創(chuàng)建RPC客戶端
*/
function getGrpcClient(){
//創(chuàng)建客戶端
let client = new harlog.HarLogService('localhost:50051',grpc.credentials.createInsecure());
return client ;
}
/*
請求JAVA端解析生成的某個HAR文件
*/
function resovleHarLog(request){
let client = getGrpcClient() ;
//請求數據
/*
let request = {
url:'',
file_name:'',
file_dir:'',
context:''
} ;
*/
client.resovleHarLog(request,function(error,response){
//console.log('Greeting:', response.code);
console.log('Greeting:', JSON.stringify(response));
})
}
/*
請求JAVA端解析指定目錄下所有的HAR文件
@param dirPath 存放HAR文件的目錄路徑
*/
function batchResovleHarlog(request){
let client = getGrpcClient() ;
client.batchResovleHarLog(request,function(error,response){
console.log('Greeting:', response.message);
})
}
//測試
resovleHarLog({
url:'www.baidu.com',
file_name:'bai.jar',
file_dir:'c://d',
context:'dsfdfdsd'
} ) ;
exports.resovleHarLog = resovleHarLog;
exports.batchResovleHarlog = batchResovleHarlog;
package com.ultrapower.ioss.proto;
import java.util.concurrent.TimeUnit;
import io.grpc.ManagedChannel;
import io.grpc.netty.shaded.io.grpc.netty.NegotiationType;
import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
public class Client {
private final ManagedChannel channel;
private final HarLogServiceGrpc.HarLogServiceBlockingStub blockingStub;
/**
* 創(chuàng)建服務端連接,并創(chuàng)建“樁”
*/
public Client(String host, int port) {
channel = NettyChannelBuilder.forAddress(host, port).negotiationType(NegotiationType.PLAINTEXT).build();
blockingStub = HarLogServiceGrpc.newBlockingStub(channel);
}
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
/**
* 向服務端發(fā)送請求
*/
public void resovleHarLog() {
try {
HarLogResovleRequest request = HarLogResovleRequest.newBuilder().setUrl("www.baidu.com").setFileName("test")
.build();
HarLogResovleResponse response = blockingStub.resovleHarLog(request);
System.out.println("result from server: " + response.getCode());
} catch (RuntimeException e) {
System.out.println("RPC failed:" + e.getMessage());
return;
}
}
public static void main(String[] args) throws Exception {
Client client = new Client("127.0.0.1", 50051);
try {
client.resovleHarLog();
} finally {
client.shutdown();
}
}
}
var grpc = require('grpc');
var PROTO_PATH = __dirname + '/../grpc/protos/HarLog.proto';
var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
var protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
//protoDescriptor + "文件中定義的package"
var harlog = protoDescriptor.com.ultrapower.grpc.har;
/*
遠程調用的resovleHarLog方法.
@param call 請求, 通過call.request可以得到請求參數
@param callback,調用完成后返回給調用端的結果
*/
function resovleHarLog(call, callback) {
let req = call.request ;
console.log(JSON.stringify(req)) ;
//callback(null, {message: 'Hello ' + call.request.name});
callback(null, {code: 300});
}
function batchResovleHarLog(call, callback) {
let req = call.request ;
console.log(JSON.stringify(req)) ;
//callback(null, {message: 'Hello again, ' + call.request.name});
callback(null, {code: 300});
}
/*
創(chuàng)建并啟動服務端
*/
function startup() {
var server = new grpc.Server();
server.addProtoService(harlog.HarLogService.service,
{resovleHarLog: resovleHarLog, batchResovleHarLog: batchResovleHarLog});
server.bind('0.0.0.0:50052', grpc.ServerCredentials.createInsecure());
server.start();
}
//啟動服務
startup() ;
exports.startup = startup;
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。