簡體   English   中英

Node.js 中面向行的流

[英]Line-oriented streams in Node.js

我正在使用 Node.js 開發一個多進程應用程序。 在這個應用程序中,父進程將產生一個子進程並使用基於 JSON 的消息協議通過管道與它通信。 我發現大型 JSON 消息可能會被“截斷”,因此發送到管道上的數據偵聽器的單個“塊”不包含完整的 JSON 消息。 此外,小的 JSON 消息可以分組在同一塊中。 每條 JSON 消息都由換行符分隔,所以我想知道是否已經有一個實用程序可以緩沖管道讀取流,以便它一次發出一行(因此,對於我的應用程序,一個 JSON 文檔一次)。 這似乎是一個非常常見的用例,所以我想知道它是否已經完成。

我很感激任何人都可以提供的任何指導。 謝謝。

也許佩德羅的承運人可以幫助你?

Carrier 幫助您在 node.js 上實現換行終止協議。

客戶可以向您發送大量線路,運營商只會在每條完成的線路上通知您。

我對這個問題的解決方案是發送 JSON 消息,每個消息都以一些特殊的 unicode 字符結尾。 一個通常不會出現在 JSON 字符串中的字符。 稱之為術語。

所以發件人只是執行“JSON.stringify(message) + TERM;” 並寫下來。 然后接收者在 TERM 上拆分傳入數據並使用 JSON.parse() 解析這些部分,這非常快。 訣竅是最后一條消息可能無法解析,因此我們只需保存該片段並在下一條消息到來時將其添加到下一條消息的開頭。 接收代碼是這樣的:

        s.on("data", function (data) {
        var info = data.toString().split(TERM);
        info[0] = fragment + info[0];
        fragment = '';

        for ( var index = 0; index < info.length; index++) {
            if (info[index]) {
                try {
                    var message = JSON.parse(info[index]);
                    self.emit('message', message);
                } catch (error) {
                    fragment = info[index];
                    continue;
                }
            }
        }
    });

其中“片段”是在某個地方定義的,它將在數據塊之間持續存在。

但什么是 TERM? 我使用了 unicode 替換字符 '\�'。 還可以使用 twitter 使用的技術,其中消息由 '\\r\\n' 分隔,推文使用 '\\n' 作為新行並且從不包含 '\\r\\n'

我發現這比搞亂包括長度等要簡單得多。

最簡單的解決方案是在每條消息之前發送 json 數據的長度作為固定長度的前綴(4 個字節?),並有一個簡單的非成幀解析器來緩沖小塊或拆分大塊。

您可以嘗試使用node-binary來避免手動編寫解析器。 查看scan(key, buffer)文檔示例 - 它完全逐行讀取。

只要換行符(或您使用的任何分隔符)只會分隔 JSON 消息而不嵌入其中,您就可以使用以下模式:

let buf = ''
s.on('data', data => {
  buf += data.toString()
  const idx = buf.indexOf('\n')
  if (idx < 0) { return } // No '\n', no full message
  let lines = buf.split('\n')
  buf = lines.pop() // if ends in '\n' then buf will be empty
  for (let line of lines) {
    // Handle the line
  }
})

暫無
暫無

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

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