Node-Serialport:当应用超时时,无法使用RxJS Observable处理传入数据

时间:2019-01-05 18:23:14

标签: node.js rxjs serial-port node-serialport node-streams

我目前正在使用serialport moduleRxJS Observables一起开发NodeJS项目。预期的“流程” /用例如下:

  1. 串行端口portName的名称是通过串行端口发送的
  2. 由于RxD和TxD相互链接,因此数据在硬件方面被“回显”
  3. 通过串行端口读取数据
  4. 传入数据由readline-parser处理并传递给RxJS Observable
  5. 如果读取的data等于先前发送的portName,则不再需要可观察的,并且将由observer.complete()完成

我能够实现上述流程,但是需要做一些进一步的实现,例如

  1. 如果在给定时间内未接收到数据,则超时
  2. 如果发生超时或其他错误,请重试再次发送命令

我正在研究超时实现,并尝试了NodeJS' setTimeout()RxJS' own timeout function。应用任何类型的超时功能时,串行端口似乎都不会读取/检索数据,这反过来会引起超时错误。

假设没有数据,乍一看这似乎还不错,因为超时会执行应做的事情。但是,我不仅可以使用软件中的仿真串行端口,还可以使用两个CP2102 USB到串行转换器(请参见代码中的注释以获取更多详细信息)来仔细检查所需的数据是否已发送到该端口。 ):

'use strict';
const Rx = require('rxjs');
const { interval } = require('rxjs');
const { timeout } = require('rxjs/operators');
const SerialPort = require('serialport');
const Readline = require('@serialport/parser-readline');


// `tries` is needed for later implementation of communcation retries
const myObservable = (portName, tries) => {
  const port = new SerialPort(portName);
  const parser = port.pipe( new Readline() );
  port.write(`${portName}\n`);

  return Rx.Observable
    .create( (observer) => {
      parser.on('data', (data) => {
        observer.next(data);
        console.log(`Detection will be: ${data == portName} (${data} vs. ${portName})`);
        if (data == portName)
        {
          port.close( (err) => {
            if (err)
            {
              console.log(`Error on closing serial port: ${err}`);
              observer.error(err);
            }
          });
          observer.complete();
        }
      })
    })
    // `timeout` is needed for later implementation of communication timeout, see comment at end of code
    // .pipe(timeout(10000))
}


const myObserver = {
  next:     x => console.log(`got data from observable: ${x}`),
  error:    err => console.error(`something wrong occurred: ${err}`),
  complete: () => console.log('done'),
};


console.log('before subscribe');
const sub = myObservable('/dev/tty.usbserial-FTG7L3FX', null).subscribe(myObserver);
// double-checked that data is sent by using software (created an emulated pair of virtual serial ports with `socat -d -d pty,raw,echo=0 pty,raw,echo=0`)
// --> data is sent, but not read/retrieved when either using `setTimeout` or RxJS' own `timeout()`
// const sub = myObservable('/dev/ttys003', null).subscribe(myObserver);
// double-checked that data is sent by using hardware interfaces (used two CP2102 modules with pairwise-crossed RxD and TxD)
// --> data is sent, but not read/retrieved when either using `setTimeout` or RxJS' own `timeout()`
// const sub = myObservable('/dev/tty.SLAB_USBtoUART', null).subscribe(myObserver);
console.log('after subscribe');


// when commenting the following `setTimeout()` data is retrieved, but does not work with `setTimeout()`
// so tried to use RxJS' `timeout()` operator --> not working either
// setTimeout(() => {
//   sub.unsubscribe();
//   console.log('unsubscribed');
// }, 10000);

我在这里想念什么?为什么在不使用任何超时但在应用超时功能时却不发送数据?


由于需要进一步调查而导致的更新:

  1. 应用timeout()时,将在超时持续时间之后发送数据,这意味着超时将触发发送数据并退出可观察对象,因为它已超时。因此,.timeout()似乎并不应用于返回的Rx.Observable,而是应用于整个函数myObservable

0 个答案:

没有答案