0

新しい情報を継続的に出力する spawn 関数があります。「データ」イベントを介してそのスポーンの出力を監視し、スポーンから新しいデータを受信するたびに放出する「更新済み」と呼ばれるカスタム エミッターを放出しました。各「データ」イベントが発生した後、partialData に格納されたデータは「更新された」エミッターで放出され、その後クリアされます。

これは正常に動作しているように見えますが、socket.io が実装されている場合、「データ」イベントが実行されているように見えますが、partialData の結果が処理されず、互いに積み重なって、「データ」イベントが数回発生します。一気に放出。この問題が発生する理由と、この問題を解決するにはどうすればよいですか? JSON文字列でこれを使用している実際のアプリケーションでは、パイルアップがノードのクラッシュを引き起こしています。

この例は、より大きなアプリケーションの単純化されたバージョンですが、症状は同じです。次の例は、ノードコードと同じディレクトリから実行する必要がある 1/5 秒ごとにタイムスタンプを発行する bash スクリプトで構成されています。node コマンドを起動すると、ターミナルはタイムスタンプと partialData の長さを出力します。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シェル スクリプトが行を出力するたびにイベントがトリガーされるという保証はありません。他の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 に答える