簡體   English   中英

stream JSON 從 REST ZDB974238714CA38DE634A7CE1D 到 Express 應用程序的最佳方法是什么?

[英]What is the best approach to stream JSON from a REST API to an Express app?

我有一個基於分子的微服務,它的端點輸出一個大的 JSON object (大約數萬個對象)

這是一個結構化的 JSON object,我事先知道它會是什么樣子。

[ // ... tens of thousands of these
  {
    "fileSize": 1155624,
    "name": "Gyo v1-001.jpg",
    "path": "./userdata/expanded/Gyo v01 (2003)"
  },
  {
    "fileSize": 308145,
    "name": "Gyo v1-002.jpg",
    "path": "./userdata/expanded/Gyo v01 (2003) (Digital)"
  }
  // ... tens of thousands of these
]

我開始研究 JSON 流,並在那里取得了一些進展,因為我知道如何使用 NodeJS ReadableStream客戶端。 我知道我可以使用oboe來解析 JSON stream。

為此,這是我基於 Express 的應用程序中的代碼。


router.route("/getComicCovers").post(async (req: Request, res: Response) => {
  typeof req.body.extractionOptions === "object"
    ? req.body.extractionOptions
    : {};
  oboe({
    url: "http://localhost:3000/api/import/getComicCovers",
    method: "POST",
    body: {
      extractionOptions: req.body.extractionOptions,
      walkedFolders: req.body.walkedFolders,
    },
  }).on("node", ".*", (data) => {
    console.log(data);
    res.write(JSON.stringify(data));
  });
});

這是moleculer中的端點

getComicCovers: {
    rest: "POST /getComicCovers",
    params: {
        extractionOptions: "object",
        walkedFolders: "array",
    },
    async handler(
        ctx: Context < {
            extractionOptions: IExtractionOptions;
            walkedFolders: IFolderData[];
        } >
    ) {
        
        const comicBooksForImport = await getCovers(
            ctx.params.extractionOptions,
            ctx.params.walkedFolders
        );

// comicBooksForImport is the aforementioned array of objects.
// How do I stream it from here to the Express app object-by-object?

        
    },
},

我的問題是:我如何 stream 這個巨大的 JSON 從 REST 端點到 Express 應用程序,以便我可以在客戶端解析它?

更新

根據@JuanCaicedo 的建議,我使用了socket.io實現。 我在服務器端和客戶端都設置了它。

但是,我確實對這段代碼有疑問

map(
    walkedFolders,
    async (folder, idx) => {
        let foo = await extractArchive(
            extractionOptions,
            folder
        );

        let fo =
            new JsonStreamStringify({
                foo,
            });

        fo.pipe(res);
        if (
            +idx ===
            walkedFolders.length - 1
        ) {
            res.end();
        }
    }
);

我收到Error [ERR_STREAM_WRITE_AFTER_END]: write after end錯誤。 我知道發生這種情況是因為響應在下一次迭代嘗試 pipe 更新值foo (這是一個流)到響應之前終止。

我該如何解決這個問題?

您是在尋求一般方法建議,還是尋求對您擁有的特定解決方案的支持?

如果是第一個,那么我認為在服務器和客戶端之間進行通信的最佳選擇是通過 websockets,也許使用Socket.io 之類的東西。 長壽命的連接將在這里為您提供很好的服務,因為傳輸所有數據需要很長時間。

然后,您可以隨時將數據從服務器發送到客戶端。 此時,您可以將服務器上的數據讀取為 node.js stream 並一次發出一個數據。

使用 Oboe 並在每個節點上寫入響應的問題在於它需要長時間運行的響應,並且在您發送所有數據之前連接很可能會中斷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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