gRPC 用于 JavaScript (Node.js):库和示例
gRPC 是一个由 Google 开发的高性能远程过程调用 (RPC) 框架。它使用 Protocol Buffers (protobuf) 进行数据序列化,并使用 HTTP/2 进行传输。在 Node.js 生态系统中,gRPC 允许您创建具有强类型、流支持和双向通信的可靠微服务。在本文中,我们将介绍在 JavaScript (Node.js) 中使用 gRPC 的主要库,并分析一个实际的服务器和客户端示例。
Node.js 中 gRPC 的主要库
在 Node.js 中使用 gRPC 主要涉及两个包:
- @grpc/grpc-js — 纯 JavaScript 实现的 gRPC。无需原生依赖,可在所有平台上运行,支持所有 gRPC 功能(一元调用、服务器和客户端流、双向流)。
- @grpc/proto-loader — 用于在运行时加载
.proto文件的实用程序。允许从 Protobuf 定义动态创建 JavaScript 对象。
要将 .proto 文件编译为静态模块,可以使用 grpc-tools(grpc-tools 的一部分),但在现代项目中,更常通过 @grpc/proto-loader 使用动态加载。
安装依赖项
npm install @grpc/grpc-js @grpc/proto-loader示例:定义 Proto 文件
创建一个包含简单服务的 helloworld.proto 文件:
syntax = "proto3";
package helloworld;
service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {}}
message HelloRequest { string name = 1;}
message HelloReply { string message = 1;}服务器端 (Node.js)
创建一个 server.js 文件:
const grpc = require('@grpc/grpc-js');const protoLoader = require('@grpc/proto-loader');const path = require('path');
const PROTO_PATH = path.join(__dirname, 'helloworld.proto');
const packageDefinition = protoLoader.loadSync(PROTO_PATH, { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true});
const helloProto = grpc.loadPackageDefinition(packageDefinition).helloworld;
function sayHello(call, callback) { const name = call.request.name || 'Guest'; callback(null, { message: `你好, ${name}!` });}
function main() { const server = new grpc.Server(); server.addService(helloProto.Greeter.service, { sayHello: sayHello }); server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => { console.log('gRPC 服务器在端口 50051 上启动'); server.start(); });}
main();客户端 (Node.js)
创建一个 client.js 文件:
const grpc = require('@grpc/grpc-js');const protoLoader = require('@grpc/proto-loader');const path = require('path');
const PROTO_PATH = path.join(__dirname, 'helloworld.proto');
const packageDefinition = protoLoader.loadSync(PROTO_PATH, { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true});
const helloProto = grpc.loadPackageDefinition(packageDefinition).helloworld;
function main() { const client = new helloProto.Greeter('localhost:50051', grpc.credentials.createInsecure());
const userName = process.argv[2] || '世界';
client.sayHello({ name: userName }, (error, response) => { if (error) { console.error('错误:', error.message); return; } console.log('服务器响应:', response.message); });}
main();启动和测试
在一个终端中启动服务器:
node server.js在另一个终端中运行客户端:
node client.js 伊万您应该