Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/408.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.js中面向行的流_Javascript_Node.js_Io_Stream_Buffer - Fatal编程技术网

Javascript Node.js中面向行的流

Javascript Node.js中面向行的流,javascript,node.js,io,stream,buffer,Javascript,Node.js,Io,Stream,Buffer,我正在使用Node.js开发一个多进程应用程序。在此应用程序中,父进程将生成子进程,并通过管道使用基于JSON的消息传递协议与之通信。我发现大型JSON消息可能会被“切断”,因此在管道上发送给数据侦听器的单个“块”并不包含完整的JSON消息。此外,小JSON消息可以分组在同一块中。每个JSON消息将由一个换行符分隔,因此我想知道是否已经有一个实用程序可以缓冲管道读取流,使其一次发出一行(因此,对于我的应用程序,一次发出一个JSON文档)。这似乎是一个非常常见的用例,所以我想知道它是否已经完成了

我正在使用Node.js开发一个多进程应用程序。在此应用程序中,父进程将生成子进程,并通过管道使用基于JSON的消息传递协议与之通信。我发现大型JSON消息可能会被“切断”,因此在管道上发送给数据侦听器的单个“块”并不包含完整的JSON消息。此外,小JSON消息可以分组在同一块中。每个JSON消息将由一个换行符分隔,因此我想知道是否已经有一个实用程序可以缓冲管道读取流,使其一次发出一行(因此,对于我的应用程序,一次发出一个JSON文档)。这似乎是一个非常常见的用例,所以我想知道它是否已经完成了

我很感激任何人能提供的指导。谢谢。

也许佩德罗餐厅可以帮你

开利帮助您实施新的生产线 通过node.js终止协议

客户端可以向您发送大量的 线路和承运人只会通知您 在每个完成的行上


最简单的解决方案是在每条消息之前发送长度固定的json数据作为固定长度前缀(4字节?),并使用一个简单的无帧解析器来缓冲小块或分割大块


您可以尝试避免手动编写解析器。查看
scan(key,buffer)
文档示例-它精确地逐行读取。

我解决这个问题的方法是发送JSON消息,每个消息都以一些特殊的unicode字符结尾。通常不会在JSON字符串中获得的字符。称之为术语

所以发送方只需执行“JSON.stringify(message)+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;
                }
            }
        }
    });
s.on(“数据”),函数(数据){
var info=data.toString().split(术语);
信息[0]=片段+信息[0];
片段='';
对于(var索引=0;索引
其中“fragment”定义为数据块之间的持久性

但术语是什么?我使用了unicode替换字符'\uFFFD'。也可以使用twitter使用的技术,其中消息由“\r\n”分隔,tweet使用“\n”表示新行,并且从不包含“\r\n”

我发现这比处理包含长度之类的问题要简单得多。

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

const 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
  }
})
const buf=''
s、 on('data',data=>{
buf+=data.toString()
常量idx=buf.indexOf('\n')
如果(idx<0){return}//No'\n',则没有完整消息
让line=buf.split('\n')
buf=lines.pop()//如果以“\n”结尾,则buf将为空
for(让行中的行){
//接电话
}
})

您是否想过只使用好的旧HTTP?你为什么要发明一种新的IPC协议?通过HTTP发送JSON消息是一个已解决的问题,node擅长HTTP。您能描述一下如何使用HTTP来实现这一点吗?现在,我不知道这会如何改变问题的性质,因为我相信您仍然会从流中读取块。您将子进程编码为常规的node.js HTTP服务器。express.js/connect.js bodyParser中间件提供了接受和发送JSON消息的功能。这将以标准node.js事件驱动的方式处理块。无需重新发明这种机制。也可以检查轴突。将每个套接字的编码设置为JSON,然后您可以轻松地发送和接收JSON对象。您需要将
const buf=''
更改为
let buf='
,以使其正常工作;无法分配给常量变量。