Как читать данные из nodejs spawn по мере их поступления - PullRequest
0 голосов
/ 24 мая 2018

У меня небольшая проблема с программой nodejs.Я пытаюсь использовать модуль child_process, но следующий код вызовет событие data только после того, как я удалю свою карту из устройства чтения карт памяти nfc.

Проблема в том, что нужный мне вывод доступенперед извлечением карты.

Например, если я положу карту в считывающее устройство, потребуется несколько секунд, чтобы напечатать несколько строк, включая UID карты.

Тогда, если я не отпущукарта, программа nfc-poll все еще будет работать, но ничего не будет выводить.Как только я извлекаю карту из ридера, она что-то выводит, а затем закрывает буфер.Это когда происходит событие data.

Мне бы хотелось, чтобы я мог как можно быстрее прочитать каждый байт, чтобы как можно быстрее выдать идентификатор карты.

function NFCReader() {
  this.reader = new events.EventEmitter()
  this.start_process()
}

NFCReader.prototype = {
  start_process: function () {
    this._process = cp.spawn('nfc-poll', [], {})
    this._process.on('close', this.restart_process.bind(this))
    //this._process.stdout.on('data', this.handle_data.bind(this))
    this._process.stdout.readableFlowing = true
    this._process.stdout.on('data', this.handle_data.bind(this))
    this._process.stderr.on('data', this.handle_error.bind(this))
  },

  handle_data: function (data) {
    var _data = data.toString()
    var uid_lines = _data
      .split('\n')
      .filter(function (line) {return line.search('UID') >= 0})

    if (uid_lines.length != 1) {
      this.reader.emit('error', 'Multiple UID found')
      return
    }

    var card_id = uid_lines[0]
      .trim()
      .split(':')[1].trim()
      .replace(/[ ]+/g, ':')

    this.reader.emit('card', card_id)
  },
}

Я пытался использовать трубу, но, похоже, это не помогло.

1 Ответ

0 голосов
/ 02 июня 2018

это функция runStream из моего репозитория release tools :

const stdin = input ? "pipe" : "ignore";
const out = new StringStream();
const child = execspawn(cmd, Object.assign(options, {
    stdio: [stdin, "pipe", 2]
}));

child.on("error", e => out.emit("error", e));

if (input) {
    input.pipe(child.stdin);
}
return child.stdout.pipe(out);

Вы можете воспроизвести ее или, если хотите, подождать пару дней, я могу выпустить какотдельный модуль.Я думаю, что уже может быть что-то подобное, хотя ...

...