node rpc 使用

摘要:
定义服务和messagenode的grpc项目地址:

什么是rpc

  • RPC(Remote Procedure Call)远程过程调用,简单的理解是一个节点请求另一个节点提供的服务
  • 本地过程调用:如果需要将本地student对象的age+1,可以实现一个addAge()方法,将student对象传入,对年龄进行更新之后返回即可,本地方法调用的函数体通过函数指针来指定。
  • 远程过程调用:上述操作的过程中,如果addAge()这个方法在服务端,执行函数的函数体在远程机器上,如何告诉机器需要调用这个方法呢?

具体细节可以参考:

https://www.jianshu.com/p/7d6853140e13

这就是rpc的作用

RPC远程调用目的:通过像调用本地服务一样远程调用另一台服务器上的服务来完成需求。

相关参考

http://doc.oschina.net/grpc?t=60135

关于grpc

gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.

gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用

说了这么多,其实就是很好用并且各个语言都支持

关于protobuf

gRPC 有一套自己的编写格式; 就是 protocol buffers

具体的格式定义可以看官网 (需要FQ)

https://developers.google.com/protocol-buffers/docs/overview

我们需要按照规定地格式来, 定义 servicemessage

node 使用grpc

项目地址:

https://github.com/grpc/grpc-node

项目初始化

#创建grpcdemo 文件夹
mkdir grpcdemo

#进入项目文件夹
cd grpcdemo

#初始化node 项目
npm init -y

#安装grpc和@grpc/proto-loader
npm install grpc @grpc/proto-loader

创建相关文件

echo "" > server.js
echo "" > client.js
echo "" > hello.proto
  • server.js 创建服务端
  • client.js 调用服务端
  • hello.proto grpc通过protocol buffers定义接口约定服务

编写 .proto 文件内定义服务

打开创建好的hello.proto文件,写入以下内容

syntax = "proto3";

//包名
package helloworld;

// 定义服务名 hello。
service hello {
    // 定义服务SayHello方法
    // HelloRequest 请求格式
    // HelloResponse返回格式
    rpc SayHello(HelloRequest) returns(HelloResponse) {}
}

// 定义调用服务需要传递的参数 和 返回的参数。
message HelloRequest {
    //这里的 1 代表第一个参数  2 代表第二个参数
    string name = 1;
    int32 age = 2;
}

// 定义返回参数的格式
message HelloResponse {
    //定义第一个参数
    string message = 1;
    // 这里我没有定义 age,那么response中也不会有
}

编写服务端

打开创建好的server.js,写入以下内容

//包引入
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');

//包定义信息,加载 hello.proto 文件的对应信息 这个文件服务端和客户端都会使用到
/*
参数:
    filename –一个或多个要加载的文件路径。 可以是绝对路径,也可以是相对于包含路径的路径。
选项 -
    配置选项:
        keepCase –保留字段名称。 默认设置是将它们更改为驼峰式。
        longs –应该用于表示long值的类型。 有效选项是Number和String 。 默认为库中的Long对象类型。
        enums –应该用于表示enum值的类型。 唯一有效的选项是String 。 默认为数值。
        bytes –应该用于表示bytes值的类型。 有效选项是Array和String 。 默认是使用Buffer 。
        defaults –在输出对象上设置默认值。 默认为false 。
        arrays –为空数组设置缺少的数组值,即使defaults值为false 。 默认为false 。
        objects –即使defaults值为false也为缺少的对象值设置空对象。 默认为false 。
        oneofs –将虚拟的oneof属性设置为当前字段的名称
        includeDirs –搜索导入的.proto文件的路径。
*/
const packageDefinition = protoLoader.loadSync('hello.proto',{
    keepCase:true,
    longs:String,
    enums:String,
    defaults:true,
    onefs:true,
});


//创建包 helloworld属性 要跟.proto 文件的包名一致
const hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld;
//创建server
const server = new grpc.Server();

//添加服务  hello为服务名 要跟.proto 文件一致
server.addService(hello_proto.hello.service, {
    //实现 SayHello 要跟.proto 文件一致定义的方法名一致
    //call 获取请求信息, callback用来向客户端返回信息
    SayHello : (call,callback) => {
        try{
            //获取.proto 文件里定义的 name,age 也就是请求参数
            let {name,age} = call.request;
            //判断有没有它,有就执行callback()【这是一个回调函数】,没有,就不执行
            //callback 两个参数  第一个参数,如果报错可以传入 error 第二参数按proto 文件里的约定传值
            callback && callback(null,{ message:`我叫${name},年龄${age}岁`});
        }catch (error) {
            console.log('服务端出错', error);
            callback && callback(error);
        }

    }
});

//绑定ip和端口
server.bind('127.0.0.1:55555',grpc.ServerCredentials.createInsecure());
//启动服务
server.start();
console.log('server start ........');

编写客户端

打开创建好的client.js,写入下面的内容

//包引入
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');

//包定义信息,加载 hello.proto 文件的对应信息 这个文件服务端和客户端都会使用到
/*
参数:
    filename –一个或多个要加载的文件路径。 可以是绝对路径,也可以是相对于包含路径的路径。
选项 -
    配置选项:
        keepCase –保留字段名称。 默认设置是将它们更改为驼峰式。
        longs –应该用于表示long值的类型。 有效选项是Number和String 。 默认为库中的Long对象类型。
        enums –应该用于表示enum值的类型。 唯一有效的选项是String 。 默认为数值。
        bytes –应该用于表示bytes值的类型。 有效选项是Array和String 。 默认是使用Buffer 。
        defaults –在输出对象上设置默认值。 默认为false 。
        arrays –为空数组设置缺少的数组值,即使defaults值为false 。 默认为false 。
        objects –即使defaults值为false也为缺少的对象值设置空对象。 默认为false 。
        oneofs –将虚拟的oneof属性设置为当前字段的名称
        includeDirs –搜索导入的.proto文件的路径。
*/
const packageDefinition = protoLoader.loadSync('hello.proto',{
    keepCase:true,
    longs:String,
    enums:String,
    defaults:true,
    onefs:true,
});


//创建包 helloworld属性 要跟.proto 文件的包名一致
const hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld

//创建客户端
console.log('init client');
//hello 方法是服务名 要跟.proto 文件的服务名一致 第一个参数是ip和端口要跟服务端保持一致
const client = new hello_proto.hello('127.0.0.1:55555',grpc.credentials.createInsecure());

//调用服务的 SayHello 方法  并 按照proto 约定传参
client.SayHello({name: 'makalo', age : 18}, (err,response) => {
    if(err){
        console.log(err);
        return ;
    }
    console.log(response.message);
});

测试

启动服务端

node server.js

image-20210222180233182

执行客户端

node client.js

image-20210222180304156

免责声明:文章转载自《node rpc 使用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SQL Server已提交读快照隔离级别的设置Chrome实用调试技巧下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

java websocket @ServerEndpoint注解说明

http://www.blogjava.net/qbna350816/archive/2016/07/24/431302.html https://segmentfault.com/q/1010000004955225 https://www.cnblogs.com/interdrp/p/4091056.html 框架是workermansocket.io...

C#调用java类、jar包方法。

一、将已经编译后的java中Class文件进行打包;打包命令JAR 如:将某目录下的所有class文件夹全部进行打包处理; 使用的命令:jar cvf test.jar -C com/ . 其中test.jar为要生成的jar包;com/ . 为指定的当前目录下的文件夹,该文件夹包括子文件夹及class文件; 二、到IKVM官方网站下载IKVM需要的组件 ...

Delphi之TComponent类

TComponent类 TComponent类直接由TPersistent派生。TComponent的独特特征是它的属性能够在设计期间通过ObjectInspector来控制,能够拥有其他组件。非可视组件也是从TComponent派生的,因此它们也继承了在设计期间可以被控制的能力。TComponent派生的非可视对象的典型例子是TTimer组件。TTim...

npm包发布

1.创建一个包module(自定义名称)目录。2.进入此目录,执行npm init,这样就在 module 目录中生成一个符合 npm 规范的 package.json 文件。3.创建一个index.js 作为包的接口,一个简单的包就制作完成了。4.使用 npm adduser 根据提示输入用户名、密码、邮箱,创建一个账号用于维护自己的包,等待创建完成,可...

(翻译)Entity Framework技巧系列之九 Tip 35 36

提示35. 怎样实现OfTypeOnly<TEntity>()这样的写法 如果你编写这样LINQ to Entities查询: 1 var results = from c in ctx.Vehicles.OfType<Car>() 2 select c; 这会返回,Cars包括那些派生自Car类型,如...

一、tomcat基础介绍及安装部署

一、tomcat介绍Tomcat服务器是一个免费的开放源代码的Web应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP网页的首选。 Tomcat和Nginx、Apache(httpd)、lighttpd等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tom...