Javascript 从gRPC服务器返回的空对象
基本上,无论我做什么,从gRPC服务器中的回调返回的JSON对象都是空的 除了使用SQLite3服务器而不是knex之外,我大部分时间都在学习教程,并且我使用了listProducts方法。我还没有尝试过其他的产品方法Javascript 从gRPC服务器返回的空对象,javascript,node.js,express,grpc,Javascript,Node.js,Express,Grpc,基本上,无论我做什么,从gRPC服务器中的回调返回的JSON对象都是空的 除了使用SQLite3服务器而不是knex之外,我大部分时间都在学习教程,并且我使用了listProducts方法。我还没有尝试过其他的产品方法 在server.js中,我从SQLite3数据库获取一些数据,并尝试在回调中返回它(在方法的底部)。我还打印了数据库中的数据,以确认我实际上得到了有效的数据 gRPC server.js 从gRPC server.js输出 回调返回到client.js,在那里调用它。但是,对
在server.js中,我从SQLite3数据库获取一些数据,并尝试在回调中返回它(在方法的底部)。我还打印了数据库中的数据,以确认我实际上得到了有效的数据 gRPC server.js 从gRPC server.js输出
回调返回到client.js,在那里调用它。但是,对象始终为空 如果我取消注释res.json({name:“jessie”});和注释res.json(result);,代码按预期工作;名称:jessie作为JSON对象发送到浏览器 这告诉我,从客户端到浏览器,数据都得到了正确的处理。因此,问题是当数据从server.js传递到client.js时 gRPC client.js 来自gRPC client.js的输出
编辑
这里有一个指向我的存储库的链接:这里的主要问题是,在服务器代码中,您的
db
方法是异步的,但您正在尝试同步访问结果。您需要在db的回调中调用listProducts
的主回调。get
以确保在尝试使用该数据库请求之前获得该数据库请求的结果。进行此更改后,您的列表产品
方法实现应该更像这样:
函数列表产品(调用、回调){
让db=new sqlite3.Database('../data/testDB.db',sqlite3.OPEN\u READONLY);
db.serialize(()=>{
db.get('SELECT NAME as NAME FROM PEEPS',(err,row)=>{
如果(错误){
控制台错误(错误消息);
}
//在此处调用回调以使用db.get的结果
回调(null,{products:row.name});
});
});
db.close();
}
为简单起见,我省略了日志记录。另外,sqlite3.Database
构造函数和db.close
在sqlite3
自述中的示例中没有回调。我建议再次检查这些函数是否实际执行回调
除此之外,既然您已经共享了定义服务的
product.proto
文件,那么还有另一个问题。ProductService
服务中的listProducts
方法声明为返回ProductList
对象。在该消息类型中,products
字段必须是Product
对象的数组。方法实现中的所有代码都指向返回该字段中的字符串,而这不会产生兼容的对象。在服务器代码中,您似乎将数据设置为空字符串,然后将数据.name
传递给回调。在这两者之间,您还启动了一些异步操作,但您没有等待它们完成,因此它们不会影响传递给回调的内容。要了解我的意思,请尝试在调用回调之前或之后添加一个console.log
。@murgatroid99感谢您指出空数据字符串。我在回调之前和之后都尝试了console.logging,但从这两个方面都收到了相同的结果;未定义。也许是因为吊装?不管怎样,我已经缩小了造成最大麻烦的编码线<代码>客户端.列表产品(…)
。由于是异步的,my index.js中的fetch
的父调用返回一个Promise{:“pending”}
。因此,这让我相信我需要使client.listProducts()
同步。我的思路正确吗?您是否尝试设置此环境变量GRPC\u VERBOSITY=DEBUG
?我尝试过,但到目前为止运气不佳。不幸的是,将主回调移到db.get()
中也无法解决问题。为了进一步解决这个问题,我将listProducts()
的主体替换为let data={products:“jeff”};控制台日志(数据);回调(空,数据)
只是看看server.js是否会返回硬编码的对象。但是,client.js正在返回一个未定义的值。那么问题就出在gRPC上了?我没有正确设置.proto吗?如果您在问题中包含了.proto
文件,这将有助于查看另一个问题。你应该在编辑中添加这个。您的listProducts
方法声明为返回ProductList
对象,但您编写的代码返回的是类似于ProductName
对象的内容。
function listProducts(call, callback) {
console.log("******** Listed the products *********");
var data = "";
let db = new sqlite3.Database('../data/testDB.db', sqlite3.OPEN_READONLY, (err) => {
if(err){
console.error(err.message);
}
console.log("connected to DB");
});
db.serialize(() => {
db.get('SELECT NAME as name FROM PEEPS', (err, row) => {
if(err){
console.error(err.message);
}
console.log(row.name);
data.name = row.name;
});
});
db.close((err) => {
if(err) {
console.error(err.message);
}
console.log('closed db');
});
callback(null, { products: data.name });
}
******** Listed the products *********
connected to DB
Jeff // Correct data from DB.
closed db
// requirements
const path = require('path');
const protoLoader = require('@grpc/proto-loader');
const grpc = require('grpc');
// gRPC client
const productProtoPath = path.join(__dirname, '..', '..', 'protos', 'product.proto');
const productProtoDefinition = protoLoader.loadSync(productProtoPath);
const productPackageDefinition = grpc.loadPackageDefinition(productProtoDefinition).product;
const client = new productPackageDefinition.ProductService('localhost:50051', grpc.credentials.createInsecure());
// handlers
const listProducts = (req, res) => {
client.listProducts({}, (err, result) => {
console.log(result);
console.log(typeof result);
// console.log(res.json(result));
res.json(result);
// res.json({ name: "jessie" });
console.log("*******************");
});
};
Server listing on port 3000
{} //Oh no! An empty JSON object!
object
*******************