场景
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