千家信息网

RPC之gRPC的使用(Java+Nodejs)

发表于:2024-10-24 作者:千家信息网编辑
千家信息网最后更新 2024年10月24日,本文介绍在Java中使用gRPC的过程。一般来说,主要包含以下的三个步骤1)在.proto文件中定义提供的服务2)使用protocol buffer编译器编译文件3)使用gRPC API来创建服务端和
千家信息网最后更新 2024年10月24日RPC之gRPC的使用(Java+Nodejs)

本文介绍在Java中使用gRPC的过程。一般来说,主要包含以下的三个步骤
1)在.proto文件中定义提供的服务
2)使用protocol buffer编译器编译文件
3)使用gRPC API来创建服务端和客户端,并进行调用。

下载和安装需要的软件

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

使用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下会生成以下两个文件夹

其中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-toolscnpm install --save google-protobuf cnpm install --save grpccnpm install --save @grpc/proto-loadercnpm 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;
文件 服务 客户 客户端 路径 生成 代码 文件夹 编译 两个 数据 机制 目录 示例 一般来说 三个 参数 序列 情况 插件 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 mysql 数据库查看编码 移动软件开发需要会什么 巩义力恒网络技术公司联系电话 新疆网络技术专业人才需求 学术数据库国际化 斑马网络技术有限公司招聘周期 西安公安部网络安全监察网站 小游戏服务器ip 电脑怎么解除网络安全模式 防火墙技术的网络安全研究 在数据库的安全控制中授权的数据 网络安全系统用什么cpu dnf哪个服务器 网络安全员是不是黑客 破坏我国网络技术的图片 聚搜索软件开发 成都市十大网络安全公司排名 海康威视服务器硬盘找不到怎么办 数据库系统中权限最低的用户 电脑软件开发要学历吗 sip网关服务器生产厂商 测试哪些模块用到了数据库 小学生网络安全教育班会总结 网络安全维护微信 万方数据库下载英文文献 北碚软件开发基地 2018系统数据库自考真题解析 全民网络安全知识竞赛平台 网络技术博客 -51cto 奉贤区个人软件开发技术指导
0