Node gRPC 初印象 && 跑起来 (1)

简介: Node gRPC 初印象 && 跑起来 (1)

1、什么是rpc

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

网络异常,图片无法展示
|
可参考官网:

grpc.io/

2、简单过程

网络异常,图片无法展示
|

3、使用协议缓冲区(Working with Protocol Buffers)

网络异常,图片无法展示
|

可参考官网

developers.google.com/protocol-bu…

4、过程

1、定义 结构

message Person {
  string name = 1;
  int32 id = 2;
  bool has_ponycopter = 3;
}
复制代码

2、写服务端

// The greeter service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}
// The response message containing the greetings
message HelloReply {
  string message = 1;
}
复制代码

3、写客户端

4、起服务测试

5、自己 起一个试试

1、新建一个文件夹  mkdir grpc-node-demo
2、初始化  npm init -y
3、npm grpc 服务  npm install grpc @grpc/proto-loader
4、启动 server node server.js
5、启动 client node client.js
6、注意端口 不要被别的服务占用,还有一点是每次修改 server.js 需要重启 服务
复制代码
  • 新建 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('helloTest.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();
//添加服务  helloTest 为服务名 要跟.proto 文件一致
server.addService(hello_proto.helloTest.service, {
    //实现 SayHello 要跟.proto 文件一致定义的方法名一致
    //call 获取请求信息, callback用来向客户端返回信息
    SayHiMark : (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:8888',grpc.ServerCredentials.createInsecure());
//启动服务
server.start();
console.log('服务已经启动,请启动客户端 ........');
复制代码
  • 新建 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('helloTest.proto',{
    keepCase:true,
    longs:String,
    enums:String,
    defaults:true,
    oneofs:true,
});
//创建包 helloworld属性 要跟.proto 文件的包名一致
const hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld
//初始化客户端
console.log('init client');
//hello 方法是服务名 要跟.proto 文件的服务名一致 第一个参数是ip和端口要跟服务端保持一致
const client = new hello_proto.helloTest('127.0.0.1:8888',grpc.credentials.createInsecure());
//调用服务的 SayHello 方法  并 按照proto 约定传参
client.SayHiMark({name: 'mark_fu', age : 18}, (err,response) => {
    if(err){
        console.log(err);
        return ;
    }
    console.log(response.message);
});
复制代码
  • 新建 helloTest.proto
syntax = "proto3";
package helloworld;
// 定义服务名 helloTest
service helloTest {
    // 定义服务 SSayHiMark 方法
    // HelloRequest 请求格式
    // HelloResponse 返回格式
    rpc SayHiMark(HelloRequest) returns(HelloResponse) {}
}
// 定义调用服务需要传递的参数 和 返回的参数。
message HelloRequest {
    //这里的 1 代表第一个参数  2 代表第二个参数
    string name = 1;
    int32 age = 2;
}
// 定义返回参数的格式
message HelloResponse {
    //定义第一个参数
    string message = 1;
    // 这里我没有定义 age,那么response中也不会有
}
复制代码
  • 结果

网络异常,图片无法展示
|

  • 非常 nice , 大功告成 !

参考 文档

www.npmjs.com/package/@gr…

6、本项目 github 地址

github.com/huanhunmao/…

更多精彩,即将袭来......



相关文章
|
9月前
|
Kubernetes 应用服务中间件 Docker
Kubernetes学习-集群搭建篇(二) 部署Node服务,启动JNI网络插件
Kubernetes学习-集群搭建篇(二) 部署Node服务,启动JNI网络插件
|
6月前
|
JavaScript 前端开发 关系型数据库
前端node学习路线
【8月更文挑战第21天】前端node学习路线
93 8
|
7月前
|
存储 中间件 API
Node中的AsyncLocalStorage 使用问题之CLS工作的问题如何解决
Node中的AsyncLocalStorage 使用问题之CLS工作的问题如何解决
|
7月前
|
JavaScript 前端开发 NoSQL
前端node如何学习进阶知识
【7月更文挑战第8天】 深化JavaScript基础,精通Node.js核心模块(如fs、http)与事件循环机制,学习Express框架及异步编程(回调、Promise、async/await),掌握数据库交互,参与实战项目,关注Node.js最新技术和最佳实践,以此提升进阶技能。
72 8
|
7月前
|
监控 JavaScript 前端开发
Node中的AsyncLocalStorage 使用问题之AsyncLocalStorage 工作时性能的问题如何解决
Node中的AsyncLocalStorage 使用问题之AsyncLocalStorage 工作时性能的问题如何解决
|
9月前
|
JavaScript 前端开发 Java
Node CLI工具原理解析(1)
前言 CLI(Command-Line Interface) 命令行界面 搞开发的同学,或多或少的都会接触到许多的命令行工具。 有生产力工具,也有有意思的小玩意、自动化任务处理等等。 命令行工具的安装方式就很多了。
|
9月前
|
JavaScript
Node CLI工具原理解析(2)
使用npm install安装依赖,会根据bin中的描述,创建1个command到exec/filepath.js的软链 软链所在目录区别于是否是global安装 这个目录可以通过npm bin指令查看
|
存储 缓存 负载均衡
重学Node系列04-进程及集群相关
创建进程 相信大家耳边听烂的一句话就是“JavaScript是单线程的”,为了弥补面对单线程对多核使用不足的问题,node很方便的提供了几个创建进程的方法:
87 0
|
设计模式 监控 JavaScript
深入浅出node中间件原理
中间件是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的。
331 12