01 - gRPC Course Overview
01.01 gRPC Introduction












01.02 Course Objective



03 - [Theory] gRPC Internals Deep Dive
介绍 grpc 的,在 golang-grpc 有,这里不重复看了
04 - [Hands-On] gRPC Project Overview & Setup
04.03 Setup gRPC Node.js Project - Create Service and Code Generation

npm i -g request
npm i -g grpc --unsafe-perm
npm i -g grpc-tools --unsafe-perm
npm i google-protobuf
npm install @grpc/grpc-js
# 如果是yarn
yarn add global xxx

根据最新的 grpc 文档,提供了@grpc/grpc-js,以下是封装的 grpc 加载 proto 文件的代码
// proto/proto.js
const path = require("path");
const grpc = require("@grpc/grpc-js");
const protoLoader = require("@grpc/proto-loader");
module.exports = (name) => {
const PROTO_PATH = path.join(__dirname, `${name}.proto`);
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
});
const protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
return protoDescriptor;
};
// proto/Dummy.proto
syntax = "proto3";
package dummy;
message DummyMessage {
}
service DummyService {
}
04.04 Server Setup and Running It
// server.js
const grpc = require("@grpc/grpc-js");
function main() {
var server = new grpc.Server();
// Not implemented. Use bindAsync() instead (用bind报错,需要用bindAsync)
server.bindAsync(
"0.0.0.0:50051",
grpc.ServerCredentials.createInsecure(),
() => {
server.start();
console.log("grpc server started");
}
);
}
main();
04.05 Client Setup - Boilerplate Code
05 - [Hands-On] gRPC Unary
05.01 What’s an Unary API


05.02 Greet API Definition

syntax = "proto3";
package greet;
option go_package="./proto/greet";
message Greeting {
string first_name = 1;
string last_name = 2;
}
message GreetRequest {
Greeting greeting = 1;
}
message GreetResponse {
string result = 1;
}
service GreetService {
// unary
rpc Greet (GreetRequest) returns (GreetResponse) {}
}
grpc_tools_node_protoc --js_out=import_style=commonjs,binary:./ --grpc_out=grpc_js:./ proto/Greet.proto
05.03 Unary API Server Implementation

// server.js
var grpc = require("@grpc/grpc-js");
var greets = require("../proto/greet/Greet_pb");
var service = require("../proto/greet/Greet_grpc_pb");
function greet(call, callback) {
var greeting = new greets.GreetResponse();
greeting.setResult(
// greeting(对象)里的数据存入request.array数组里
"Hello " +
call.request.getGreeting().getFirstName() +
" " +
call.request.getGreeting().getLastName()
);
callback(null, greeting);
}
function main() {
var server = new grpc.Server();
server.addService(service.GreetServiceClient.service, { greet: greet });
// Not implemented. Use bindAsync() instead (用bind报错,需要用bindAsync)
server.bindAsync(
"0.0.0.0:50051",
grpc.ServerCredentials.createInsecure(),
() => {
server.start();
console.log("grpc server started");
}
);
}
main();
05.04 Unary API Client Implementation
// client.js
var grpc = require("@grpc/grpc-js");
var greets = require("../proto/greet/Greet_pb");
var service = require("../proto/greet/Greet_grpc_pb");
function main() {
var client = new service.GreetServiceClient(
"localhost:50051",
grpc.credentials.createInsecure()
);
unary(client);
}
function unary(client) {
var request = new greets.GreetRequest();
var greeting = new greets.Greeting();
greeting.setFirstName("Jerry");
greeting.setLastName("Tom");
request.setGreeting(greeting);
client.greet(request, (error, response) => {
if (!error) {
console.log("Greeting Response: " + response.getResult());
} else {
console.error(error);
}
});
}
main();
05.05 Side Note - Install nodemon

05.07 [Solution] Sum API
// calculator.proto
syntax = "proto3";
package calculator;
message SumRequest {
int32 first_number = 1;
int32 second_number = 2;
}
message SumResponse {
int32 result = 1;
}
service CalculatorService {
// unary
rpc Sum (SumRequest) returns (SumResponse) {};
}
// server.js
var grpc = require("@grpc/grpc-js");
var calc = require("../proto/calculator/calculator_pb");
var service = require("../proto/calculator/calculator_grpc_pb");
function sum(call, callback) {
var sumResponse = new calc.SumResponse();
sumResponse.setResult(
call.request.getFirstNumber() + call.request.getSecondNumber()
);
callback(null, sumResponse);
}
function main() {
var server = new grpc.Server();
server.addService(service.CalculatorServiceService, { sum: sum });
// Not implemented. Use bindAsync() instead (用bind报错,需要用bindAsync)
server.bindAsync(
"0.0.0.0:50051",
grpc.ServerCredentials.createInsecure(),
() => {
server.start();
console.log("grpc server started");
}
);
}
main();
// client.js
var grpc = require("@grpc/grpc-js");
var calc = require("../proto/calculator/calculator_pb");
var service = require("../proto/calculator/calculator_grpc_pb");
function main() {
var client = new service.CalculatorServiceClient(
"localhost:50051",
grpc.credentials.createInsecure()
);
callSum(client);
}
function callSum(client) {
var request = new calc.SumRequest();
request.setFirstNumber(10);
request.setSecondNumber(15);
client.sum(request, (error, response) => {
if (!error) {
console.log("Sum Response: " + response.getResult());
} else {
console.error(error);
}
});
}
main();
