gRPC中Java和node进行异构通信-互为客户端和服务端

场景

gPRC简介以及Java中使用gPRC实现客户端与服务端通信(附代码下载):

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108711541

上面介绍了在Java中使用gPRC进行通信的搭建方式。

如果是使用node作为客户端与Java的服务端进行通信 ,或者是node作为服务端与Java客户端进行通信怎么办。

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

使用Java进行gPRC服务端和客户端的搭建参照上面,在上面搭建好的基础上,

打开WebStorm新建project,然后新建package.json

{
  "name": "grpc-examples",
  "version": "0.1.0",
  "dependencies": {
    "@grpc/proto-loader": "^0.1.0",
    "async": "^1.5.2",
    "google-protobuf": "^3.0.0",
    "grpc": "^1.11.0",
    "lodash": "^4.6.1",
    "minimist": "^1.2.0"
  }
}

这里的代码内容可以去gRPC的github上的示例代码中去复制

https://github.com/grpc/grpc/blob/v1.30.x/examples/node/package.json

然后打开Ternimal

npm install

进行安装依赖,就会在项目目录下生成node_modules目录。

然后在项目下新建proto文件夹,在此目录下将之前Java项目中的Person.proto复制过来

syntax = "proto3";

package com.badao.proto;

option optimize_for =SPEED;
option java_package = "com.badao.grpcjava";
option java_outer_classname = "BadaoDataInfo";
option java_multiple_files = true;

service PersonService {

    rpc GetRealNameByUsername(MyRequest) returns (MyResponse) {}

}


message MyRequest {
    string username = 1;
}

message MyResponse {
    string realname = 2;
}

动态代码生成的方式

前面在Java中搭建客户端和服务端时都需要调用插件去生成代码,在node中可以使用动态代码生成的方式和静态代码的方式去搭建。

搭建node的rRPC客户端

在项目下新建app目录,在app目录下新建grpcClient.js

var PROTO_FILE_PATH = 'D:\Workspace\WebStormWorkspace\nodegRPC\proto\Person.proto';
var grpc = require('grpc');
var grpcService = grpc.load(PROTO_FILE_PATH).com.badao.proto;

var client = new grpcService.PersonService('localhost:8899',grpc.credentials.createInsecure());
client.GetRealNameByUsername({username:'公众号:霸道的程序猿'},function (error,responseData) {
    console.log(responseData)
});

注意这里的路径就是proto文件的绝对路径,这样代码会在运行时去生成。

然后下面的

var grpcService = grpc.load(PROTO_FILE_PATH).com.badao.proto;

后面的路径要与proto文件中

package com.badao.proto;

指定的一致。

启动Java的服务端,然后运行node的客户端,在grpcClient.js上右击run

搭建node的服务端

在app下新建grpcServer.js

var PROTO_FILE_PATH = 'D:\Workspace\WebStormWorkspace\nodegRPC\proto\Person.proto';
var grpc = require('grpc');
var grpcService = grpc.load(PROTO_FILE_PATH).com.badao.proto;

var server = new grpc.Server();

server.addService(grpcService.PersonService.service,{
    getRealNameByUsername:getRealNameByUsernameImpl
});

server.bind('localhost:8899',grpc.ServerCredentials.createInsecure());
server.start();

function getRealNameByUsernameImpl(call,callback) {
    console.log("username:"+call.request.username)
    callback(null,{realname:'公众号:霸道的程序猿'});
}

前面的内容与搭建客户端一致,在进行方法的具体实现时,左边的getRealNameByUsername

就是proto文件中定义的接口的方法名,右边getRealNameByUsernameImpl是在当前js中方法的具体实现方法。

运行node的服务端,然后运行java的客户端。

静态代码生成的方式

静态代码生成的方式与上面Java端搭建客户端与服务端的流程差不多,就是使用插件根据prpto文件生成代码,然后再去编写代码。

首先确保电脑上已经安装了protoc并配置了环境变量。

具体流程可以参照下面

ProtoBuf的介绍以及在Java中使用protobuf将对象进行序列化与反序列化:

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108667427

然后在node项目下打开Ternimal

npm install grpc-tools --save-dev
npm install google-protobuf --save
npm install grpc --save

安装所需要的依赖,然后就会在node_modules下找到grpc-tools下bin下的grpc_node_plugin.exe

和protoc.exe

这里直接使用配置进环境变量的prptoc.exe,就不能再一层层进入到node_modules所在的目录了。

然后在Ternimal下继续执行

protoc--js_out=import_style= commonjs,binary:./--plugin=protoc-gen-grpc=./node_modules/grpc-tools/bin/grpc_node_plugin.exe --grpc_out=./ proto/Person.proto

注意这里的执行前的路径是在项目的根目录下,因为已经配置了protoc的环境变量,所以直接使用prptoc开头才能识别命令。

然后---js_out后面是固定的写法 在binary:后面的路径和后面--grpc_out的路径是分别生成在proto中定义的message的代码和service的代码路径,这里./就是当前路径,就是相对于proto在同一个路径下,然后proto-gen-grpc是跟的node_modules中grpc_node_plugin.exe的路径,最后面跟的是prpto文件相对于项目的路径,因为命令是在项目根目录下执行的。

生成代码成功后就在proto文件所在的路径下生成了两个js文件。那么生成代码成功。

使用静态代码搭建客户端

在项目下app下新建grpcClient2.js

var service = require('../proto/Person_grpc_pb');
var messages = require('../proto/Person_pb');

var gprc = require('grpc');

var client = new service.PersonServiceClient('localhost:8899',gprc.credentials.createInsecure());

var request = new messages.MyRequest();
request.setUsername('公众号:霸道的程序猿');

client.getRealNameByUsername(request,function (error,respData) {
    console.log(respData.getRealname());
})

注意这里的路径,service就是上面生成的Person_grpc_pb.js文件的路径,messages就是

上面生成的Person_pb.js文件的路径。

使用静态代码搭建服务端

在项目下app下新建grpcServer2.js

var service = require('../proto/Person_grpc_pb');
var messages = require('../proto/Person_pb');

var grpc = require('grpc');

var server = new grpc.Server();

server.addService(service.PersonServiceService,{
    getRealNameByUsername:getRealNameByUsernameImpl
})

server.bind('localhost:8899',grpc.ServerCredentials.createInsecure());
server.start();

function getRealNameByUsernameImpl(call,callback) {
    console.log("username:"+call.request.getUsername())
    var myResponse = new messages.MyResponse();
    myResponse.setRealname('公众号:霸道的程序猿')
    callback(null,myResponse);
}


然后运行服务端后再运行客户端

此时在服务端

 

示例代码下载

https://download.csdn.net/download/BADAO_LIUMANG_QIZHI/12887305

原文地址:https://www.cnblogs.com/badaoliumangqizhi/p/13729433.html