【发布时间】:2019-08-15 14:17:36
【问题描述】:
我有一个简单的 Express/gRPC 项目,它应该将硬编码的 JSON 对象打印到浏览器和控制台。问题是对象没有及时返回给客户端以从 gRPC 服务器接收它。
我的项目其实是this Codelabs项目的修改。不过,我只实现了listBooks 方法,并将Go 更改为Express。我能够成功地从 Codelabs 项目中的服务器获得响应。
起初我想避免回调,而是尝试使用 promises (promises, promisfy...)。但我没有成功。另外,从this 的回答中,我现在知道 Node gRPC 没有实现同步:
“节点 gRPC 没有同步调用。” - murgatroid99
话虽如此,输出显示没有接收到数据。我需要做什么才能让客户端等待数据可用?
products.proto
syntax = "proto3";
package products;
service ProductService {
rpc ListProduct (Empty) returns (ProductList) {}
}
message Empty {}
message Product {
int32 id = 1;
string name = 2;
string price = 3;
}
message ProductList {
repeated Product products = 1;
}
server.js
var PROTO_PATH = __dirname + '/products.proto';
var grpc = require('grpc');
var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
var productsProto = grpc.loadPackageDefinition(packageDefinition).products;
var products = [{
id: 123,
name: 'apple',
price: '$2'
}];
function listProduct(call, callback){
console.log(products);
callback(null, products);
}
function main(){
var server = new grpc.Server();
server.addService(productsProto.ProductService.service,
{ListProduct: listProduct}
);
server.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure());
console.log("server started");
server.start();
}
main();
client.js
var PROTO_PATH = __dirname + '/products.proto';
var grpc = require('grpc');
var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
var products = grpc.loadPackageDefinition(packageDefinition).products;
var client = new products.ProductService('localhost:50051', grpc.credentials.createInsecure());
function printResponse(error, response){
if(error){
console.log('Error: ', error);
}
else{
console.log(response);
}
}
function listProducts() {
client.listProduct({}, function(error, products){
printResponse(error, products);
});
}
exports.listProducts = listProducts;
client-server.js
const express = require('express');
const app = express();
var client = require('./client');
app.get('/', (req, res) => {
console.log('Hello World!');
client.listProducts();
res.send('Hello World!');
});
app.listen(3000, () =>
console.log('Example app listening on port 3000!'),
);
实际结果
gRPC 服务器显然已经拥有该对象,但我将其打印到控制台只是为了好玩。客户端将其回调结果打印到控制台,但仅打印一个空对象。
server.js 输出
[ { id: 123, name: 'apple', price: '$2' } ]
client.js 输出
Hello World!
{ products: [] }
复制
- 打开 2 个终端,
cd进行项目 - 在一个终端运行
node server.js - 在另一个终端运行
node client-server.js - 打开浏览器到
localhost:3000
【问题讨论】: