[英]Empty object returned from gRPC Server
基本上,無論我做什么,從我的gRPC服務器中的回調返回的JSON對象都是空的。
在大多數情況下,我將按照本教程進行操作,但我使用的是SQLite3服務器而不是knex,並且已經使用listProducts方法。 我還沒有嘗試過其他產品方法。
在server.js中,我從SQLite3數據庫中獲取了一些數據,然后嘗試在回調中將其返回(位於方法的底部)。 我還從數據庫中打印出數據,以確認我實際上正在獲取有效數據。
gRPC server.js
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 });
}
從gRPC server.js輸出
******** Listed the products *********
connected to DB
Jeff // Correct data from DB.
closed db
回調返回到被調用的client.js 。 但是,該對象始終為空。
如果我取消注釋res.json({name:“ jessie”}); 並評論res.json(result); ,代碼按預期工作; 名稱:jessie作為JSON對象發送到瀏覽器。
因此,這告訴我從客戶端到瀏覽器的數據均已正確處理。 因此,問題在於何時將數據從server.js傳遞到client.js 。
gRPC client.js
// 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("*******************");
});
};
gRPC client.js的輸出
Server listing on port 3000
{} //Oh no! An empty JSON object!
object
*******************
編輯這里是我的資料庫的鏈接: https : //github.com/burke212/grpc-node
這里的主要問題是,在服務器代碼中,您的db
方法是異步的,但是您嘗試同步訪問結果。 你需要調用主回調listProducts
在回調db.get
,以確保您有一個數據庫請求的結果嘗試使用它之前。 進行此更改后, listProducts
方法實現應如下所示:
function listProducts(call, callback) {
let db = new sqlite3.Database('../data/testDB.db', sqlite3.OPEN_READONLY);
db.serialize(() => {
db.get('SELECT NAME as name FROM PEEPS', (err, row) => {
if(err){
console.error(err.message);
}
// Call the callback here to use the result of db.get
callback(null, { products: row.name });
});
});
db.close();
}
為簡單起見,我省略了日志記錄。 另外,在sqlite3
自述文件的示例中, sqlite3.Database
構造函數和db.close
沒有回調。 我建議再次檢查這些函數是否實際接受回調。
除此之外,既然您已經共享了定義服務的product.proto
文件,那么還有另一個問題。 ProductService
服務中的listProducts
方法被聲明為返回ProductList
對象。 在該消息類型中, products
字段必須是Product
對象的數組。 方法實現中的所有代碼都旨在返回該字段中的字符串,而這不會導致兼容對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.