Javascript Node.js中面向行的流
我正在使用Node.js开发一个多进程应用程序。在此应用程序中,父进程将生成子进程,并通过管道使用基于JSON的消息传递协议与之通信。我发现大型JSON消息可能会被“切断”,因此在管道上发送给数据侦听器的单个“块”并不包含完整的JSON消息。此外,小JSON消息可以分组在同一块中。每个JSON消息将由一个换行符分隔,因此我想知道是否已经有一个实用程序可以缓冲管道读取流,使其一次发出一行(因此,对于我的应用程序,一次发出一个JSON文档)。这似乎是一个非常常见的用例,所以我想知道它是否已经完成了 我很感激任何人能提供的指导。谢谢。也许佩德罗餐厅可以帮你 开利帮助您实施新的生产线 通过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文档)。这似乎是一个非常常见的用例,所以我想知道它是否已经完成了
最简单的解决方案是在每条消息之前发送长度固定的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='
,以使其正常工作;无法分配给常量变量。