我正在通过node.js调用Ruby脚本,该脚本通过stdout返回数据,我已经设法让节点发送一些的数据通过其web套接字,但我缺少行,并没有真正了解我在做什么。从研究来看,我正在使用一个流,但我无法理解很多文档,因为这都是非常新的,超出了我的理解:(
当通过bash shell运行时,我的Ruby脚本输出如下:
{"element":"SENS02","data":{"type":"SEN","descr":"T100"}}
{"element":"SENS01","data":{"type":"SEN","descr":" "}}
{"element":"LED1","data":{"type":"LED","state":"1"}}
{"element":"LED2","data":{"type":"LED","state":"0"}}
当在控制台上运行时一切都很好-当我通过我的node.js脚本调用它时,我只得到每2行,所以例如node会输出;
{"element":"SENS02","data":{"type":"SEN","descr":"T100"}}
{"element":"LED1","data":{"type":"LED","state":"1"}}
我的node.js脚本部分如下;
var cp = require('child_process');
var tail = cp.spawn('test.rb');
// Get updates from ruby script //
tail.stdout.on('data', function(chunk) {
var pumper = chunk.toString().slice(0,58);
var closer = JSON.parse(pumper);
socket.emit('MAP.room1', closer);
});
如果有人能帮助的话,我也会偶尔崩溃一下,出现以下错误;
定义:0
^ SyntaxError:输入的意外结束在对象。解析(本机)
我需要能够输出从我的ruby脚本收到的每一行。任何回答的人都请使用我自己的代码,而不是随机的例子,因为它只会让我在试图理解什么与什么相关以及"它对我意味着什么"时感到非常困惑。我试着看。pipe,但所有的例子让我困惑,我不明白如何适应他们为我自己的脚本。从ruby输出的是JS对象一次一行,我需要我的web套接字一次发出完全相同的东西一个对象。
完成console.log(chunk.toString())
以获得可读输出它减轻了一些奇怪的东西——额外的换行或其他东西。
控制台输出为;
{"element":"SENS02","data":{"type":"SEN","descr":"T100"}}
{"element":"SENS01","data":{"type":"SEN","descr":" "}}
{"element":"LED1","data":{"type":"LED","state":"1"}}
{"element":"LED2","data":{"type":"LED","state":"0"}}
我怎样才能绕过这个?这是否会导致我的其他"意外输入结束"错误?
如果我执行var pumper = chunk.slice(0,-1); console.log(pumper.toString())
,那么我得到如上所示的输出,没有奇数/额外/rouge换行符。我仍然没有进一步的向前得到这个输出正好是web套接字虽然。
我可以从web套接字中得到这个,但它显示我仍然有n ?
["{"element":"SENS02","data":{"type":"SEN","descr":"T100"}}n{"element":"SENS01","data":{"type":"SEN","descr":" "}}"]}
我需要把它恢复成一条平直的线,就像我在控制台设置的那样…
因此,按照下面的建议完成后,我现在通过使用这段代码获得所需的输出。我仍然在控制台中登录了): Unexpected end of input
,这似乎来自我从Ruby脚本中获得的附加换行。在没有崩溃的情况下运行脚本几天后,出现所有数据都完好无损地通过并解析出web套接字。我仍然需要阅读并充分理解for
正在做什么,但除此之外,它似乎已经解决了我的问题。
tail.stdout.on('data', function(chunk) {
var closer = chunk.toString()
var sampArray = closer.split('n');
for (var i = 0; i < sampArray.length; i++) {
try {
var newObj = JSON.parse(sampArray[i]);
socket.emit('MAP.room1', newObj);
} catch (err) {
console.log('): ' + err.message);
}
}
});
如果您打算对每个数据块使用JSON.parse()
,那么您需要在换行符n
上预解析每个块。
JSON.parse
不能解析以换行符分隔的多个对象为同一字符串中的两个不同对象
这些单独有效:
"{"element":"SENS02","data":{"type":"SEN","descr":"T100"}}"
"{"element":"SENS02","data":{"type":"SEN","descr":"T100"}}n"
"{"element":"SENS02","data":{"type":"SEN","descr":"T100"}}rn"
这不是:
"{"element":"SENS02","data":{"type":"SEN","descr":"T100"}}n{"element":"SENS01","data":{"type":"SEN","descr":" "}}"
如果目的是解析整个数据结构,那么您需要将ruby脚本的输出重新组织为如下所示:
{
"elements": [
{
"name": "SENS02",
"data": {
"type": "SEN",
"descr": "T100"
}
},
{
"name": "SENS01",
"data": {
"type": "SEN",
"descr": " "
}
},
{
"name": "LED1",
"data": {
"type": "LED",
"state": "1"
}
},
{
"name": "LED2",
"data": {
"type": "LED",
"state": "0"
}
}
]
}
如何解析输入(粗略示例)
var sample = "{"element":"SENS02","data":{"type":"SEN","descr":"T100"}}n{"element":"SENS01","data":{"type":"SEN","descr":" "}}n{"element":"LED1","data":{"type":"LED","state":"1"}}n{"element":"LED2","data":{"type":"LED","state":"0"}}";
var sampArray = sample.split('n');
for (var i = 0; i < sampArray.length; i++) {
try {
var newObj = JSON.parse(sampArray[i]);
// socket.emit(newObj);
} catch (err) {
console.log('): ' + err.message);
}
}
试试spawn
你的ruby脚本,exec
正在缓冲输出,这可能就是你所看到的原因。
p。S
用try-catch
块包裹JSON.parse
,并在失败时打印失败的数据