如何在 NodeJS 中实现 gRPC 服务?

言鼎科技 2023-06-21 392

什么是 gRPC?

gRPC:谷歌远程过程调用是谷歌开发的开源框架。gRPC 允许您为远程过程调用定义请求和响应,并通过处理其余部分来减少您的努力。gRPC 的特点:

  • 现代的

  • 快速地

  • 具有低延迟

  • 高效负载均衡

  • 支持串流

  • 插件认证

  • 监控数据

  • 建立在 HTTP/2 之上

  • 语言无关

教程目标:在 NodeJS 中实现 gRPC 服务

我们都知道 NodeJs 有多流行和成功。因此,在本教程中,我们将在 NodeJs 中实现 gRPC 服务。我们将构建一个演示应用程序并执行 CRUD 操作。因此,事不宜迟,让我们开始在我们的 NodeJS 应用程序中实现 gRPC 服务。

Bacancy 将减少您的开发困难。相信最好的!相信我们!
如果您正在为您的梦想项目寻找潜在的 NodeJS 开发人员,请联系 Bacancy。我们拥有技术精湛的开发人员,他们拥有出色的问题解决方法。别想太多!只需联系我们并从我们这里聘请 NodeJs 开发人员!

在 NodeJS 中实现 gRPC 服务的步骤

初始化节点环境

如何在 NodeJS 中实现 gRPC 服务?
npm 初始化 -y

安装 gRPC 服务器

如何在 NodeJS 中实现 gRPC 服务?
npm install --save grpc @grpc/proto-loader uuid express body-parser

grpc:它将安装 gRPC 服务器
/proto-loader:它将加载 protobuf 文件
uuid:它将为学生创建随机哈希 ID

现在,创建students.proto、server.jsclient.js文件。单个学生项目将具有 - id、name、age 和 coursename

如何在 NodeJS 中实现 gRPC 服务?
语法=“proto3”;消息学生{
   字符串 ID = 1;
   字符串名称 = 2;
   int32 年龄 = 3;
   字符串课程名称 = 4;}

Students 定义了我们的学生请求消息格式,其中每个消息请求都有一个唯一的id、学生的姓名、学生的年龄以及学生选择的课程名称。

在 proto 中定义 StudentService

创建 RPC 服务。所有 CRUD 操作都将在名为 StudentsService 的服务中可用。

如何在 NodeJS 中实现 gRPC 服务?
...服务学生服务{
   rpc GetAllStudents (Empty) 返回 (NewsList) {}}消息空{}留言学生名单{
  重复学生 students = 1;}

news.proto文件的全部代码如下所示。

如何在 NodeJS 中实现 gRPC 服务?
语法=“proto3”;服务学生服务{
   rpc GetAllNews (Empty) 返回 (NewsList) {}}消息学生{
   字符串 ID = 1;
   字符串名称 = 2;
   int32 年龄 = 3;
   字符串课程名称 = 4;}消息空{}留言学生名单{
  重复学生 students = 1;}const grpc = require("@grpc/grpc-js");const PROTO_PATH = "./news.proto";var protoLoader = require("@grpc/proto-loader");常量选项 = {
 多头:字符串,
 一个:真实的,
 保持大小写:真实,
 枚举:字符串,
 默认值:真,};var packageDefinition =protoLoader.loadSync(PROTO_PATH, options);const newsProto=grpc.loadPackageDefinition(packageDefinition);const {v4:uuidv4}=require(“uuid”)const server = new grpc.Server();让学生们= [
 {编号:“a68b823c-7ca6-44bc-b721-fb4d5312cafc”,名称:“约翰·博尔顿”,年龄:22岁,课程名称:“课程1”
 },
 {编号:“34415c7c-f82d-4e44-88ca-ae2a1aaa92b7”,名称:“约翰·博尔顿”,年龄:22岁,课程名称:“课程2”
 },  ];server.addService(StudentsProto.StudentService.service, {
 getAll: (_, 回调) => {
   回调(空,{学生});
 },});server.bind("127.0.0.1:30043",grpc.ServerCredentials.createInsecure());console.log("服务器运行在 http://127.0.0.1:50051");服务器.start();

首先,我们导入了@grpc/grpc-js@grpc/proto-loader库。名为PROTO PATH 的常量变量将保存students.proto文件的位置。稍后,loadSync 方法会将 proto 文件加载到 gRPC 中。loadPackageDefinition方法加载包定义。之后,为了初始化服务器实例(),我们将调用 new grpc.server

创建客户端存根

我们将调用 Server 的 addService 方法中定义的 getAll 方法作为客户端的第二个参数,如下所示。

如何在 NodeJS 中实现 gRPC 服务?
const PROTO_PATH = "./students.proto";const grpc = require("@grpc/grpc-js");var protoLoader = require("@grpc/proto-loader");var packageDefinition=protoLoader.loadSync(PROTO_PATH, {
 多头:字符串,
 一个:真实的,
 保持大小写:真实,
 枚举:字符串,
 默认值:真,});const StudentService = grpc.loadPackageDefinition(packageDefinition).StudentService;const client = new StudentService(
 “本地主机:30043”,
 grpc.credentials.createInsecure());

getAll 方法:获取所有学生

从客户端变量调用服务器中的 getAll 方法。

如何在 NodeJS 中实现 gRPC 服务?
...const 客户端 = 新服务(
 “本地主机:30043”,
 grpc.credentials.createInsecure());client.getAll(null, (err, data) => {
 如果 (!err) 抛出错误
   控制台日志(数据);});

现在执行 client.js 代码如下:

如何在 NodeJS 中实现 gRPC 服务?
// 节点客户端.js{
 学生: [
   {编号:“a68b823c-7ca6-44bc-b721-fb4d5312cafc”,名称:“约翰·博尔顿”,年龄:22岁,课程名称:“课程1”
 },
 {编号:“34415c7c-f82d-4e44-88ca-ae2a1aaa92b7”,名称:“约翰·博尔顿”,年龄:22岁,课程名称:“课程2”
 },
]}

我们已经从 gRPC 客户端成功执行了 gRPC 服务方法。导出 NewsService 实例后,您可以将其导入另一个文件以调用方法。

如何在 NodeJS 中实现 gRPC 服务?
const PROTO_PATH = "./students.proto";const grpc = require("@grpc/grpc-js");var protoLoader = require("@grpc/proto-loader");var packageDefinition=protoLoader.loadSync(PROTO_PATH, {
 多头:字符串,
 一个:真实的,
 保持大小写:真实,
 枚举:字符串,
 默认值:真,});const StudentService = grpc.loadPackageDefinition(packageDefinition).StudentService;const client = new StudentService(
 “本地主机:30043”,
 grpc.credentials.createInsecure());module.exports = 客户端;

我们现在可以将客户端导入到不同的文件中。我们将为我们希望采取的每个步骤制作一个单独的文件。我们将创建一个名为 get test.js 的文件,该文件导入客户端并调用 getAll 方法。

如何在 NodeJS 中实现 gRPC 服务?
// 测试.jsconst client = require("./client");client.getAll(null, (err, data) => {
 如果 (!err) 抛出错误
   控制台日志(数据);});

插入学生记录

为插入数据创建一个新方法。打开 proto 文件并在服务下,您可以添加一个带有新方法名称的 RPC。在这里,我们的方法名称是 Insert under StudentService 服务,如下所示。

如何在 NodeJS 中实现 gRPC 服务?
...服务学生服务{
   rpc GetAll(空)返回(StudentList){}
   rpc 插入(学生)返回(学生){}}...

该服务将接受 Student 消息并返回新的 Student 对象。

如何在 NodeJS 中实现 gRPC 服务?
...server.addService(StudentsProto.StudentService.service, {
 getAll: (_, 回调) => {
   回调(空,{学生});
 },
 插入:(调用,回调)=> {
   让 Student = call.request;
   Student.id = uuidv4();
   Students.push(学生);
   回调(空,新闻);
 },});...

删除学生

现在,我们将编写删除学生的代码。这是相同的代码片段。

如何在 NodeJS 中实现 gRPC 服务?
...服务学生服务{
   rpc GetAll(空)返回(StudentList){}
   rpc 插入(学生)返回(学生){}
   rpc 删除(学生)返回(学生){}}消息 StudentRequestId {
   字符串 ID = 1;}...

在这里,请求是StudentRequestId,它将返回一条空消息。

来自 server.js 的代码片段如下所示。

如何在 NodeJS 中实现 gRPC 服务?
...
 删除:(调用,回调)=> {
   让 existingStudentIndex = Students.findnidex(
n =>n.id == call.request.id);如果(现有学生索引!= -1){
Students.splice(existingStudentIndex,1)
回调(空,{});
   }},...

更新现有学生

为了更新数据,我们将在原型文件中添加一个方法。

如何在 NodeJS 中实现 gRPC 服务?
...服务学生服务{
   rpc GetAll(空)返回(StudentList){}
   rpc 插入(学生)返回(学生){}
   rpc 删除(学生)返回(学生){}
   rpc 更新(学生)返回(学生){}}...

该方法接受 Student 消息并使用编辑后的 News 对象进行响应。更新学生数据的代码如下所示。

如何在 NodeJS 中实现 gRPC 服务?
...
 更新:(调用,回调)=> {
   让 existingStudent = Students.find(n=> n.id== call.request.id);
如果(现有学生){
existingStudent.name = call.request.name;
existingStudent.age = call.request.age;
existingStudent.CourseName =call.request.CourseName;
回调(空,现有学生);},...

得到一个学生

让我们在 proto 文件中设置一个方法:

如何在 NodeJS 中实现 gRPC 服务?
...服务学生服务{
   rpc GetAll(空)返回(StudentList){}
   rpc 获取(学生)返回(学生){}
   rpc 插入(学生)返回(学生){}
   rpc 删除(学生)返回(学生){}
   rpc 更新(学生)返回(学生){}}...

Get 方法需要 ID 作为请求消息并返回 Student 消息。这是 server.js 文件中的实现:

如何在 NodeJS 中实现 gRPC 服务?
...
 得到:(调用,回调)=> {
   让 Student = Students.find(n=>n.id == call.request.id)
   如果(学生)= {
   回调(空,学生);}
 },...

我们从调用参数对象中获取 id。id 用于从 Students 数组中检索相应的学生项目。使用作为参数传递的检索到的学生项目调用回调函数,这使得客户端获取学生项目。

如何在 NodeJS 中实现 gRPC 服务?
// 测试.js// 获取所有消息const client = require("./client");client.getAll({}, (error, students) => {
 如果(错误)抛出错误;
 控制台日志(学生);});//添加一个学生客户.插入(
 {
   name: "标题新闻3",
   年龄:11岁,
   CourseName: "这里是图片地址",
 },
 (错误,学生)=> {
   如果(错误)抛出错误;
   console.log("成功创建学生。");
 });// 编辑学生客户端.更新(
 {
   编号:“a68b823c-7ca6-44bc-b721-fb4d5312cafc”,
   name: "标题新闻3",
   年龄:11岁,
   CourseName: "这里是图片地址",
 },
 (错误,学生)=> {
   如果(错误)抛出错误;
   console.log("成功更新一个学生。");
 });//删除一个学生客户.删除(
 {
   编号:“34415c7c-f82d-4e44-88ca-ae2a1aaa92b7”,
 },
 (错误,学生)=> {
   如果(错误)抛出错误;
   console.log("成功删除学生记录。");
 });

现在,运行文件:

如何在 NodeJS 中实现 gRPC 服务?
节点测试

使用 Http 服务器

我们现在已经构建并准备好了服务器、原型和客户端。将 Node 服务器附加到 client.js,以便我们服务器中的端点将调用gRPC新闻服务中的过程。这是端点。

  • /GET 端点将调用 getAll 子例程以获取数据库中的所有学生。

  • /save POST 端点将调用插入子例程来创建新的学生项目。

  • /update PUT 将调用更新子例程来编辑/更新学生项目。

  • /remove DELETE 将调用删除子例程来删除学生项目。

这是 Nodejs 中的代码:

如何在 NodeJS 中实现 gRPC 服务?
const client = require("./client");const express = require("快递");const bodyParser = require("body-parser");const app = express();app.use(bodyParser.json());app.use(bodyParser.urlencoded({ extended: false }));app.get("/", (req, res) => {
client.getAll(null, (err, data) => {
如果(!错误){
重新发送(数据。学生)
}
});});app.post("/保存", (req, res) => {
console.log(req.body.CourseName)
让新学生={
名称:req.body.name,
年龄:req.body.age,
课程名称:req.body.CourseName
};
client.insert(newStudent, (err, data) => {
如果(错误)抛出错误;res.send({data:data, msg:"学生创建成功"})
});});app.post("/update", (req, res) => {
const updateStudent = {
id: req.body.id,
名称:req.body.name,
年龄:req.body.age,
课程名称:req.body.CourseName
};
client.update(updateStudent, (err, data) => {
如果(错误)抛出错误;
res.send({msg:"学生更新成功"})
});});app.post("/remove", (req, res) => {
client.remove({ id: req.body.Student_id }, (err, _) => {
如果(错误)抛出错误;
console.log("学生删除成功");
//res.redirect("/");
res.send({msg:"学生删除成功"})
});});常量端口 = 3000;app.listen(PORT, () => {
console.log("服务器运行在端口 %d", PORT);});

结论

所以,这是关于我们如何在 NodeJS 中实现 gRPC 服务。我希望您阅读本教程的目的对您有所帮助。如果您是 NodeJS 爱好者,请随时访问NodeJS 教程页面并了解有关 Node.js 的更多信息。我们始终乐于接受建议和反馈。如果您有任何问题,请给我们回信。Bacancy 拥有拥有基础和高级知识的最佳 NodeJS 开发人员;联系我们为您的应用程序聘请 NodeJs 开发人员。

言鼎科技主做软件开发,微信小程序,网站开发,软件外包,手机APP开发。如有需要记得联系我们!

The End