【问题标题】:Ensuring NodeJS spawn stdout.on activates on newlines only确保 NodeJS spawn stdout.on 仅在换行符上激活
【发布时间】:2015-05-25 20:02:07
【问题描述】:

我正在使用 spawn 功能通过 NodeJS 运行一个外部程序,如下所示:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);


app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');

  var spawn = require('child_process').spawn;
  var java = spawn('java', ['-jar', 'misc.jar']);
  java.stdout.on('data', function(data) {
      console.log(data.toString());
      io.emit('chat message', data.toString())
  });

});

预期的标准输出应该是这样的(换行符就位):

>java -jar misc.jar
0000
0
0001
1
...

但是当我通过 NodeJS/Socket.io 运行它时,我得到:

listening on *:3000
000
0
0

000
1
1
...

我想确保对java.stdout.on('data', function(data){... 的调用仅在数据为换行符或退出子进程时发生

当将data 推入java.stdout.on('data', function(data) {... 调用时,Socket.io/NodeJS 似乎还有其他一些模式。

我怎样才能确保这一点?

更新: 好的,现在我似乎有了以下代码的换行符:

  var lineBuffer = "";
  java.stdout.on('data', function(data) {  
      lineBuffer += data.toString();
      var lines = lineBuffer.split("\n");

      if (lines.length > 1) {
          var line = lines[0];
          console.log(line);
          io.emit('chat message', line);
          lineBuffer = lines[1];
      }
  });

但是,我看到了一个新问题。 console.log(line) 显示的文本与 emit(line) 命令不同:

listening on *:3000
0000
0
0001
1
...

对比(注意它甚至不是从 0001 开始的)

0002
2 0003
3 0004
4 0005
5 0006
6 0007
7
0008
8 0009 

这是来自io.emit(...) 命令。所以console.log(...) 显示了正确的数据,但socket.io.emit 不是!

【问题讨论】:

  • 我在下面所做的更改是否仍然会发生这种情况?
  • 是的,不幸的是。我想我会在星期一恢复工作时多玩它!
  • 啊,我想我知道为什么其中的一部分会以奇数的形式出现。这与从 CDN 下载 socket.io 的延迟有关。我在 html 中手动包含了 socket.io.js 代码,一开始的垃圾就消失了!

标签: java javascript node.js sockets socket.io


【解决方案1】:

您的 java.stdout 是 Node.js 中的 Readable Stream。可读流'data' 事件只是在数据进入时返回数据块,而不管换行符在哪里。

如果您只想在有换行符时发出消息,则必须自己实现该逻辑。试试这个:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res) {

    res.sendFile(__dirname + '/index.html');

    var spawn = require('child_process').spawn;
    var java = spawn('java', ['-jar', 'misc.jar']);

    var lineBuffer = "";

    java.stdout.on('data', function(data) {

        lineBuffer += data.toString();

        var lines = lineBuffer.split("\n");

        for (var i = 0; i < lines.length - 1; i++) {

            var line = lines[i];

            console.log(line);
            io.emit('chat message', line);
        }

        lineBuffer = lines[lines.length - 1];
    });

    java.stdout.on('end', function() {

        console.log(lineBuffer);
        io.emit('chat message', lineBuffer);
    });
});

【讨论】:

  • 非常酷!我想说我要改变的一件事是lineBuffer = lines[1],而不是我可以让 lineBuffer = 除了第 [0] 个元素之外的所有行。不过,我需要查找它的语法。
  • 我现在好像有新问题了。我会把它附加到我的问题中
  • 好点!我已更改我的代码以解决在一个数据事件中返回多行的情况。我建议一次发出所有可用的行并将最后一行放入缓冲区。
猜你喜欢
  • 2016-11-06
  • 1970-01-01
  • 2020-12-27
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
相关资源
最近更新 更多