0

我有一个不断输出新信息的生成功能。我正在通过“数据”事件监视该生成的输出,并发出一个自定义发射器,我称之为“更新”,每当从该生成接收到新数据时就会发出该发射器。在每个 'data' 事件发生后,存储在 partialData 中的数据会与 'updated' 发射器一起发射,然后被清除。

这似乎工作正常,但是当实现 socket.io 时,似乎运行了“数据”事件,但部分数据中的结果没有得到处理,相互堆积,然后发生了几次“数据”事件一下子发出来。为什么会发生这种情况,我该如何解决这个问题?在实际应用程序中,我在 JSON 字符串中使用它,并且堆积导致节点崩溃。

此示例是大型应用程序的简化版本,但症状相同。以下示例包含一个 bash 脚本,该脚本每 1/5 秒发出一个时间戳,该时间戳应从与节点代码相同的目录中运行。启动节点命令后,终端将输出部分数据的时间戳和长度。每当您浏览到 127.0.0.1:3000 时,您都会注意到 partialData 的长度发生了变化。这就是问题所在。

发射器.sh:

#!/bin/bash
while [[ 1 ]]; do
    echo `date +%s`
    usleep 20000
done

发射器.js:

var express = require('/usr/local/lib/node_modules/express');
var http = require('http');
var spawn = require('child_process').spawn;
var events = require('events');
var util = require('util');

var app = express();
var server = http.createServer(app);
var io  = require('/usr/local/lib/node_modules/socket.io').listen(server);

runCommand = function (arg1) {
    var self = this;
    var partialData = '';
    var cmd = spawn(arg1);
    cmd.stdout.setEncoding('utf8');
    cmd.stdout.on('data', function(data) {
        partialData += data.substr(0,data.length-1);
        console.log('data: '+partialData.trim());
        console.log('length: '+partialData.length);
        partialData = '';       
        self.emit('updated', data);
    });
}
util.inherits(runCommand, events.EventEmitter);

var result = new runCommand('./emitter.sh');

app.get('/', function(req, res){
    res.send(
    "<script src='/socket.io/socket.io.js'></script>\n"+
    "<script>\n"+
    "var socket=io.connect('http://127.0.0.1:3000');\n"+
    "</script>\n"
    );
});

server.listen(3000);

io.sockets.on('connection', function(webSocket) {
    console.log('socket established');
});
4

1 回答 1

0

不能保证data每次您的 shell 脚本输出一行时都会触发该事件;当发生其他 I/O 时(如您的socket.io示例),允许缓冲输出。

如果你想要线路支持,你可以使用该readline模块:

var cmd = spawn(arg1);
cmd.stdout.setEncoding('utf8');
var linereader = require('readline').createInterface(cmd.stdout, cmd.stdin);
linereader.on('line', function(line) {
  ...
});
于 2013-11-04T20:01:59.690 回答