簡體   English   中英

從gRPC服務器返回的空對象

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM