grpc简单使用 java_RPC之gRPC的使用(Java+Nodejs)

本文详细介绍了如何在Java和Nodejs中使用gRPC进行RPC通信。首先,文章讲解了在.proto文件中定义服务,然后通过protoc编译器生成服务端和客户端代码。接着,展示了在Java中实现服务端服务类和启动类,以及Nodejs客户端的创建和调用方法。最后,提供了Java客户端的示例代码,展示了如何向服务端发送请求并接收响应。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文介绍在Java中使用gRPC的过程。一般来说,主要包含以下的三个步骤

1)在.proto文件中定义提供的服务

2)使用protocol buffer编译器编译文件

3)使用gRPC API来创建服务端和客户端,并进行调用。

下载和安装需要的软件

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

使用Maven构建gRPC

1)修改pmo.xml

UTF-8

3.7.0

1.19.0

io.grpc

grpc-netty-shaded

${grpc.version}

io.grpc

grpc-protobuf

${grpc.version}

io.grpc

grpc-stub

${grpc.version}

com.google.protobuf

protobuf-java

${protobuf.version}

com.google.protobuf

protobuf-java-util

${protobuf.version}

kr.motd.maven

os-maven-plugin

1.6.1

org.xolstice.maven.plugins

protobuf-maven-plugin

0.6.1

false

com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}

grpc-java

io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}

compile

compile-custom

默认情况下,该插件会查找 src/main/proto路径下的proto文件。该在路径下的任何子文件夹都会作为proto文件中使用的包路径。

2)在src/main/proto下创建proto文件(HarLog.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);

}

3)编译文件

mvn protobuf:compile

mvn compile

在target\generated-sources\protobuf下会生成以下两个文件夹

3cd8c167a65c75f24b7436872b8e071b.png

其中java文件夹下面包含了我们定义的message,而grpc-java下存放的是服务端和客户端都要使用的service。

基于上面的proto文件,生成了两个java文件

1,HarLogServiceGrpc.java 位于grpc-java下

2,HarLogProto.java等其他文件位于java下

4)服务端服务实现类代码

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 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 responseObserver) {

responseObserver.onNext(HarLogResovleResponse.newBuilder().setCode(200).build());

responseObserver.onCompleted();

}

}

5)服务端启动类

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();

}

}

Nodejs端客户端

1)添加依赖

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

2)客户端代码

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;

/*

创建RPC客户端

*/

function getGrpcClient(){

//创建客户端

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;

基于Java的客户端

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;

/**

* 创建服务端连接,并创建“桩”

*/

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);

}

/**

* 向服务端发送请求

*/

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();

}

}

}

基于Nodejs的服务端

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});

}

/*

创建并启动服务端

*/

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;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值