最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

通過NodeJS輕松使用GRPC和協(xié)議緩沖區(qū)的方法

 更新時(shí)間:2024年10月16日 09:57:49   作者:學(xué)會(huì)種一棵樹  
本文介紹了GRPC和協(xié)議緩沖區(qū)的基本概念,并展示了如何在NodeJS應(yīng)用程序中使用它們,GRPC是一個(gè)高性能RPC框架,協(xié)議緩沖區(qū)則用于定義服務(wù)和序列化消息,本文給大家介紹如何在NodeJS應(yīng)用程序中使用GRPC和協(xié)議緩沖區(qū),感興趣的朋友一起看看吧

本文將對(duì)GRPC和協(xié)議緩沖區(qū)進(jìn)行基本介紹。接下來,我將展示如何在NodeJS應(yīng)用程序中使用GRPC和協(xié)議緩沖區(qū)

GRPC是什么

GRPC是一個(gè)開源高性能RPC框架,那么RPC到底是做什么的呢?請(qǐng)看下面的例子

function getEmployee() {
  return "ABCD";
}
function greetEmployee()
{
  let employee = getEmployee();
  console.log("Greet",employee) 
} 

在這里,我們有一個(gè)getEmployee函數(shù),它返回一個(gè)Employee Name,另一個(gè)函數(shù)greetEmployee,它調(diào)用getEmployee并獲取該員工的Name,然后打印一個(gè)Greeting

這里的greetEmployee調(diào)用getEmployee是一個(gè)常規(guī)函數(shù)調(diào)用。

現(xiàn)在,如果getEmployeegreetEmployee函數(shù)位于不同的地址空間中,或者它們位于由網(wǎng)絡(luò)分隔的2個(gè)不同的主機(jī)中,則該函數(shù)調(diào)用稱為“遠(yuǎn)程過程調(diào)用”(Remote Procedure Call, RPC)。在這里,具有getEmployee函數(shù)的System充當(dāng)服務(wù)器,而具有greetEmployee函數(shù)的System充當(dāng)客戶端。

什么是Protocol Buffer (協(xié)議緩沖區(qū))

協(xié)議緩沖區(qū)是默認(rèn)情況下在GRPC中使用的接口定義語言。

  • 它有助于定義服務(wù)器提供的各種服務(wù)
  • 它有助于定義系統(tǒng)中使用的有效負(fù)載的結(jié)構(gòu)
  • 它有助于對(duì)消息進(jìn)行序列化(轉(zhuǎn)換為特殊的二進(jìn)制格式),并通過服務(wù)器和客戶端之間的線路進(jìn)行發(fā)送。

在本文后面的部分中,我們將在使用NodeJS應(yīng)用程序時(shí)看到如何使用protocol buffers(協(xié)議緩沖區(qū))。

支持哪些不同類型的RPC?

Unary RPC

這是可用的最簡單的RPC??蛻舳嗽诖颂幭蚍?wù)器發(fā)送請(qǐng)求消息。服務(wù)器處理該請(qǐng)求,然后將響應(yīng)消息發(fā)送回客戶端

在本文中,這是我們將重點(diǎn)介紹的grpc。

Server Streaming RPC

在此RPC中,客戶端將請(qǐng)求消息發(fā)送到服務(wù)器,然后服務(wù)器以流方式將一系列消息發(fā)送回客戶端。

Client Streaming RPC

在此RPC中,客戶端以流方式向服務(wù)器發(fā)送一系列消息。然后,服務(wù)器處理所有這些請(qǐng)求,然后將響應(yīng)消息發(fā)送回客戶端。

Bidirectional Streaming RPC

在此RPC中,客戶端以流方式向服務(wù)器發(fā)送一系列消息。然后,服務(wù)器處理請(qǐng)求,然后以流方式將一系列消息發(fā)送回客戶端。

如何在NodeJS中使用GRPC和協(xié)議緩沖區(qū)

使用以下命令創(chuàng)建一個(gè)名為grpc-nodejs-demo的文件夾并在其中初始化nodejs

mkdir grpc-nodejs-demo
cd grpc-nodejs-demo
npm init

這將創(chuàng)建一個(gè)package.json文件。

修改package.json文件

將package.json文件替換為以下內(nèi)容

{
  "name": "grpc-nodejs-demo",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    "@grpc/proto-loader": "^0.1.0",
    "grpc": "^1.11.0",
    "lodash": "^4.6.1"
  },
  "author": "Name",
  "license": "MIT"
}

在這里我們添加了3個(gè)依賴項(xiàng)

  • @ grpc / proto_loader和grpc依賴項(xiàng)將幫助我們?cè)趹?yīng)用程序中使用GRPC和協(xié)議緩沖區(qū)
  • lodash是通用實(shí)用程序依賴項(xiàng)。這將有助于簡化一些代碼邏輯

package.json文件更新后。運(yùn)行以下命令以安裝依賴項(xiàng)

npm install

定義協(xié)議緩沖區(qū)

在此示例中,我們將構(gòu)建一個(gè)將employee ID作為輸入,并提供employee詳細(xì)信息作為輸出的服務(wù)。

所需的服務(wù)接口和有效負(fù)載將在協(xié)議緩沖區(qū)文件中指定。協(xié)議緩沖區(qū)文件的擴(kuò)展名為.proto

現(xiàn)在,我們來創(chuàng)建.proto文件。

在項(xiàng)目中創(chuàng)建一個(gè)名為proto的文件夾。在proto文件夾中,創(chuàng)建一個(gè)名為employee.proto的文件,并向其中添加以下代碼

syntax = "proto3";
package employee;
service Employee {
  rpc getDetails (EmployeeRequest) returns (EmployeeResponse) {}
}
message EmployeeRequest {
  int32 id = 1;
}
message EmployeeResponse{
  EmployeeDetails message = 1;
}
message EmployeeDetails {
  int32 id = 1;
  string email = 2;
  string firstName = 3; 
  string lastName = 4;
}

那么,我們?cè)谶@里到底做了什么?

syntax="proto3";表示我們要使用Protocol Buffer version 3。

package employee; 表示我們正在創(chuàng)建一個(gè)名為employee的程序包,我們將在其中定義我們的services

service Employee {
  rpc getDetails (EmployeeRequest) returns (EmployeeResponse) {}
}

上述腳本表明我們正在創(chuàng)建一個(gè)稱為Employee的服務(wù)。在此服務(wù)中,我們正在創(chuàng)建一個(gè)名為getDetails的函數(shù)(rpc),該函數(shù)接受EmployeeRequest類型的輸入并以EmployeeResponse格式提供響應(yīng)

接下來,我們需要定義EmployeeRequestEmployeeResponse。這是在以下腳本中完成的

message EmployeeRequest {
  int32 id = 1;
}
message EmployeeResponse{
  EmployeeDetails message = 1;
}
message EmployeeDetails {
  int32 id = 1;
  string email = 2;
  string firstName = 3; 
  string lastName = 4;
}

在這里,我們看到消息EmployeeRequest具有單個(gè)類型為int32和名稱id的字段。此處分配的數(shù)字1是字段號(hào),它在消息的編碼和解碼過程中提供幫助。定義的每個(gè)字段應(yīng)具有唯一的字段號(hào)

我們還看到EmployeeResponse有一個(gè)類型為EmployeeDetails的自定義字段,并且名稱消息的字段編號(hào)為1。這意味著甚至也必須定義EmployeeDetails,如上所示。

EmployeeDetails具有4個(gè)字段,包括類型int32string。它們都有唯一的字段編號(hào)(unique field numbers)

Field numbers between 1 -15 use 1 byte of space during encoding. and field numbers from 2 - 2047 uses 2 bytes for encoding and hence will take up more space. So try to design in such a way that the field numbers are between 1 - 15 as much as possible

1 -15之間的編號(hào)在編碼過程中使用1個(gè)字節(jié)的空間。并且2-2047的字段編號(hào)使用2個(gè)字節(jié)進(jìn)行編碼,因此會(huì)占用更多空間。因此,請(qǐng)嘗試以盡可能多的字段編號(hào)介于1到15之間的方式進(jìn)行設(shè)計(jì)

Creating the GRPC Server

創(chuàng)建一個(gè)名為server.js的文件

首先,讓我們包括我們需要的所有庫,并定義.proto文件所在的位置

const PROTO_PATH = __dirname + '/proto/employee.proto';
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');
const _ = require('lodash');

接下來,我們需要加載.proto文件。這是使用protoLoader庫的loadSync方法完成的。

let packageDefinition = protoLoader.loadSync(
    PROTO_PATH,
    {keepCase: true,
     longs: String,
     enums: String,
     defaults: true,
     oneofs: true
    }
);

接下來,從已加載的原始文件包定義中,我們需要獲取所需的包。這是使用以下腳本完成的

let employee_proto = grpc.loadPackageDefinition(packageDefinition).employee;

在這里,我們將employee包放入employee_proto變量中。

employee_proto現(xiàn)在將具有所有原型定義。

接下來,我們需要?jiǎng)?chuàng)建一些虛擬employees數(shù)據(jù)供服務(wù)器使用。創(chuàng)建一個(gè)名為data.js的文件,并將以下腳本添加到其中

let employees = [{
    id: 1,
    email: "abcd@abcd.com",
    firstName: "First1",
    lastName: "Last1"   
},
{
    id: 2,
    email: "xyz@xyz.com",
    firstName: "First2",
    lastName: "Last2"   
},
{
    id: 3,
    email: "temp@temp.com",
    firstName: "First3",
    lastName: "Last3"   
},
];
exports.employees = employees;

接下來,我們需要將data.js導(dǎo)入server.js。為此,在server.js中添加以下腳本

function main() {
  let server = new grpc.Server();
  server.addService(employee_proto.Employee.service, {getDetails: getDetails});
  server.bind('0.0.0.0:4500', grpc.ServerCredentials.createInsecure());
  server.start();
}

let server = new grpc.Server();

是創(chuàng)建新GRPC Server的腳本

.proto文件中,我們注意到在Employee Service內(nèi)部有一個(gè)名為getDetails的函數(shù)。

server.addService(employee_proto.Employee.service,{getDetails:getDetails});

是我們?cè)谄渲刑砑覵ervice實(shí)現(xiàn)的腳本。該腳本表明,我們?cè)?strong>employee_proto.Employee Service中添加了getDetails函數(shù)。然后,我們將此服務(wù)添加到服務(wù)器。

server.bind('0.0.0.0:4500', grpc.ServerCredentials.createInsecure()); 是指示服務(wù)器將在端口4500上啟動(dòng)且沒有身份驗(yàn)證的腳本

server.start(); 是實(shí)際啟動(dòng)服務(wù)器的腳本

現(xiàn)在待處理的主要事情是實(shí)現(xiàn)getDetails函數(shù)。下面的腳本顯示了實(shí)現(xiàn)

function getDetails(call, callback) {
  callback(null, 
    {
       message: _.find(employees, { id: call.request.id })
    });
}

這里的call具有請(qǐng)求參數(shù),而回callback 是我們需要定義實(shí)現(xiàn)的地方。

在callback 內(nèi)部,我們收到一條消息:_.find(employees,{id:call.request.id}),其中顯示以下內(nèi)容

  • 從Input獲取員工ID-call.request.id
  • 搜索employees列表以查找具有該ID的員工
  • Return employee詳細(xì)信息

這樣就完成了服務(wù)器的實(shí)現(xiàn)。這是server.js的完整腳本

const PROTO_PATH = __dirname + '/proto/employee.proto';
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');
const _ = require('lodash');
let packageDefinition = protoLoader.loadSync(
    PROTO_PATH,
    {keepCase: true,
     longs: String,
     enums: String,
     defaults: true,
     oneofs: true
    });
let employee_proto = grpc.loadPackageDefinition(packageDefinition).employee;
let {employees} = require('./data.js');
function getDetails(call, callback) {
  console.log('client call :%j', call)
  callback(null, 
    {
       message: _.find(employees, { id: call.request.id })
    });
}
function main() {
  let server = new grpc.Server();
  server.addService(employee_proto.Employee.service, {getDetails: getDetails});
  server.bind('0.0.0.0:4500', grpc.ServerCredentials.createInsecure());
  server.start();
}
main();

Creating the GRPC Client

創(chuàng)建一個(gè)名為client.js的文件 將以下腳本復(fù)制到client.js

const PROTO_PATH = __dirname + '/proto/employee.proto';
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');
let packageDefinition = protoLoader.loadSync(
    PROTO_PATH,
    {keepCase: true,
     longs: String,
     enums: String,
     defaults: true,
     oneofs: true
    }
);
let employee_proto = grpc.loadPackageDefinition(packageDefinition).employee;

上面的腳本以與server.js中相同的方式將employee包加載到employee_proto變量中

接下來,我們需要一種可以調(diào)用RPC的方式。在這種情況下,我們需要能夠調(diào)用服務(wù)器中實(shí)現(xiàn)的getDetails函數(shù)。

為此,我們需要在客戶端中創(chuàng)建一個(gè)存根(stub)。這是使用以下腳本完成的。

  let client = new employee_proto.Employee('localhost:4500', grpc.credentials.createInsecure());

client Stub將幫助我們調(diào)用在服務(wù)器上運(yùn)行的Employee Service中定義的getDetails函數(shù)。服務(wù)器依次在端口4500上運(yùn)行。代碼行還指示未使用身份驗(yàn)證

最后,我們可以使用以下腳本調(diào)用getDetails函數(shù)

let employeeId = 1;
 client.getDetails({id: employeeId}, function(err, response) {
    console.log('Employee Details for Employee Id:',employeeId,'\n' ,response.message);
  });

如前所述,客戶端存根可以像正常函數(shù)調(diào)用一樣幫助我們?cè)诜?wù)器中調(diào)用getDetails函數(shù)。為此,我們將employeeId作為輸入。

最后,Response 進(jìn)入response 變量。然后,我們將打印響應(yīng)消息。

完整的client.js代碼如下

const PROTO_PATH = __dirname + '/proto/employee.proto';
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');
let packageDefinition = protoLoader.loadSync(
    PROTO_PATH,
    {keepCase: true,
     longs: String,
     enums: String,
     defaults: true,
     oneofs: true
    });
let employee_proto = grpc.loadPackageDefinition(packageDefinition).employee;
function main() {
  let client = new employee_proto.Employee('localhost:4500',
                                       grpc.credentials.createInsecure());
  let employeeId;
  if (process.argv.length >= 3) {
    employeeId = process.argv[2];
  } else {
    employeeId = 1;
  }
  client.getDetails({id: employeeId}, function(err, response) {
    console.log('Employee Details for Employee Id:',employeeId,'\n' ,response.message);
  });
}
main();

Running The Server and Client

打開命令提示符并使用以下命令運(yùn)行服務(wù)器

node server.js

打開一個(gè)新的命令提示符,并使用以下命令運(yùn)行客戶端

node client.js

當(dāng)我們運(yùn)行客戶端時(shí)。它將打印以下輸出

Employee Details for Employee Id: 1 
 { id: 1,
  email: 'abcd@abcd.com',
  firstName: 'First1',
  lastName: 'Last1' 
 }

運(yùn)行截圖

原文地址

How to Easily use GRPC and Protocol Buffers with NodeJS

關(guān)于GRPC Streams in NodeJS參考作者原文

我的示例源碼地址

到此這篇關(guān)于如何通過NodeJS輕松使用GRPC和協(xié)議緩沖區(qū)的文章就介紹到這了,更多相關(guān)NodeJS使用GRPC和協(xié)議緩沖區(qū)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解nodejs中的process進(jìn)程

    詳解nodejs中的process進(jìn)程

    這篇文章主要介紹了nodejs中的process進(jìn)程,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下
    2017-03-03
  • Node.js readline 逐行讀取、寫入文件內(nèi)容的示例

    Node.js readline 逐行讀取、寫入文件內(nèi)容的示例

    本篇文章主要介紹了Node.js readline逐行讀取、寫入文件內(nèi)容的示例,運(yùn)用readline逐行讀取的兩種實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-03-03
  • 關(guān)于npm主版本升級(jí)及其相關(guān)知識(shí)點(diǎn)總結(jié)

    關(guān)于npm主版本升級(jí)及其相關(guān)知識(shí)點(diǎn)總結(jié)

    npm是Node.js默認(rèn)的包管理器,以javascript?編寫的軟件包管理系統(tǒng)用于分享和使用代碼,下面這篇文章主要給大家介紹了關(guān)于npm主版本升級(jí)及其相關(guān)知識(shí)點(diǎn)總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • nodejs連接mongodb數(shù)據(jù)庫實(shí)現(xiàn)增刪改查

    nodejs連接mongodb數(shù)據(jù)庫實(shí)現(xiàn)增刪改查

    本篇文章主要結(jié)合了nodejs操作mongodb數(shù)據(jù)庫實(shí)現(xiàn)增刪改查,包括對(duì)數(shù)據(jù)庫的增加,刪除,查找和更新,有興趣的可以了解一下。
    2016-12-12
  • Node.js全局對(duì)象Global的實(shí)現(xiàn)

    Node.js全局對(duì)象Global的實(shí)現(xiàn)

    在Nodejs下全局變量和全局函數(shù)都是可以使用global來訪問到的,本文主要介紹了Node.js全局對(duì)象Global的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • 詳解nodejs中express搭建權(quán)限管理系統(tǒng)

    詳解nodejs中express搭建權(quán)限管理系統(tǒng)

    本篇文章主要介紹了詳解express搭建權(quán)限管理系統(tǒng),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • 使用Node.js實(shí)現(xiàn)簡易MVC框架的方法

    使用Node.js實(shí)現(xiàn)簡易MVC框架的方法

    下面小編就為大家?guī)硪黄褂肗ode.js實(shí)現(xiàn)簡易MVC框架的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • node.js express框架實(shí)現(xiàn)文件上傳與下載功能實(shí)例詳解

    node.js express框架實(shí)現(xiàn)文件上傳與下載功能實(shí)例詳解

    這篇文章主要介紹了node.js express框架實(shí)現(xiàn)文件上傳與下載功能,結(jié)合具體實(shí)例形式詳細(xì)分析了node.js express框架針對(duì)文件上傳與下載的前后臺(tái)相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2019-10-10
  • Windows下安裝NodeJS的詳細(xì)步驟

    Windows下安裝NodeJS的詳細(xì)步驟

    這篇文章主要介紹了Windows下安裝NodeJS,本文分步驟通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • Node.js性能診斷利器Clinic.js原理剖析與實(shí)戰(zhàn)應(yīng)用

    Node.js性能診斷利器Clinic.js原理剖析與實(shí)戰(zhàn)應(yīng)用

    Clinic.js正是為解決這一痛點(diǎn)而生——它是一套低開銷、可視化、自動(dòng)化的 Node.js 性能診斷工具集,由 NearForm 團(tuán)隊(duì)開發(fā)并開源,本文將從宏觀認(rèn)知、底層原理到三大核心工具的實(shí)戰(zhàn)應(yīng)用,系統(tǒng)性地解析 Clinic.js的強(qiáng)大能力
    2026-05-05

最新評(píng)論

越西县| 成都市| 洪雅县| 拉萨市| 翁源县| 杂多县| 东平县| 兰考县| 泸水县| 乐山市| 紫阳县| 科技| 汪清县| 木兰县| 瑞昌市| 秭归县| 芦山县| 蕉岭县| 宣汉县| 新郑市| 濮阳市| 安福县| 河西区| 金昌市| 绥德县| 平潭县| 衡水市| 渝中区| 中江县| 遂昌县| 左权县| 什邡市| 罗城| 宜宾县| 邢台市| 韶山市| 盐山县| 上饶市| 敦化市| 阿合奇县| 祁东县|