【问题标题】:nodejs-serialport => RE-Establish connection to port after closednodejs-serialport => 关闭后重新建立与端口的连接
【发布时间】:2017-09-19 18:49:45
【问题描述】:

根据我的最后一个问题SerialPort 'close' event never fire。我无法检测到COM 是否断开连接,因此我创建了自己的检测方法。

我已经创建了时间戳,并每隔 1 秒使用interval() 检查它是否已连接。 当它检测到COM 被拔出时,我会尝试使用SerialPort 重新建立连接或重新实例化端口,就像您将在下面的代码中看到的那样。

当它尝试重新连接时,我得到了Error: Access denied.

有没有办法刷新或清理缓存? ,因为我认为服务器在没有正确关闭时仍然保持连接。

我也尝试过port.close(),但它让我失望了:Error: Port is not open.

var comPort = '\\\\.\\COM7',
    lastDataTime,
    lastresult,
    count = 0,
    lastDataTime,
    comStatus,
    error;
var port = new SerialPort(comPort, function (err) {
    if (err) {
        comStatus = false;
        return console.log('Error: ', err.message);
    }
});
const parser = port.pipe(new Readline());
port.on('open', function () {
    console.log('~Port is open.');

    parser.on('data', function (data) {
        comStatus = true;
        lastDataTime = Date.now();
        if (++count == 10) {
            count = 0;
            lastresult = data;
        }
    });
});

setInterval(function () {
    if (Date.now() - lastDataTime > 1000 || !comStatus) {
        comStatus = false;
        port.close();
        port = new SerialPort(comPort, function (err) {
            if (err) {
                error = 'Error: ' + err.message;
                return console.log(error);
            }
        });
    }
}, 1000);


app.get('/', function (req, res) {
    res.send((comStatus) ? lastresult : 'Disconnected - ' + error);
    console.log(lastresult);
})

谢谢!

【问题讨论】:

    标签: node.js node-serialport


    【解决方案1】:

    正如您在/node_modules/serialport/lib/serialport.js 中看到的:close-可能不会发出事件(与disconnect 不同)。

    您可以像下面这样在本地添加console.log 以进行简单的调试。

    附:我在Win7x32 上对其进行了测试。发出Close-事件。

    SerialPort.prototype._disconnected = function(err) {
      this.paused = true;
      this.emit('disconnect', err);
    
      // add: console.log('1', this.closing);
    
      if (this.closing) {
        return;
      }
    
      // add: console.log('2', this.fd);
    
      if (this.fd === null) {
        return;
      }
    
      this.closing = true;
      if (process.platform !== 'win32') {
        this.readable = false;
        this.serialPoller.close();
      }
    
      // add: console.log('3');
    
      SerialPortBinding.close(this.fd, function(err) {
        // add: console.log('4', this._events.close.toString());
    
        this.closing = false;
        if (err) {
          debug('Disconnect close completed with error: ', err);
        }
        this.fd = null;
        this.emit('close'); // it's your target
      }.bind(this));
    };
    

    重新连接示例

    var SerialPort = require('serialport');
    var port = new SerialPort('COM1', {autoOpen: false, baudRate: 9600});
    
    function open () {
        port.open(functon (err) {
            if (!err)
               return;
    
            console.log('Port is not open: ' + err.message);
            setTimeout(open, 10000); // next attempt to open after 10s
        });
    }
    
    port.on('open', function() {
        function send() {
            if (!port.isOpen()) // v5.x require
                return console.log('Port closed. Data is not sent.');
    
            port.write(123, function (err) {
                if (err)
                    console.log('Error on write: ' +  err.message)
    
                port.drain(() => console.log('DONE'));
            });
        }
    
        setInterval(send, 1000);
    });
    
    port.on('close', function () {
        console.log('CLOSE');
        open(); // reopen 
    });
    
    port.on('data', (data) => console.log('Data: ' + data));
    port.on('error', (err) => console.error('Error: ', err.message));
    
    open(); // open manually
    

    【讨论】:

    • 感谢您的帮助!事件发生后,我尝试重新连接COM,但重新连接后数据停止流动。你知道断开后如何重新连接吗?
    【解决方案2】:

    根据serialport.io,

    resume() 方法导致显式暂停的可读流 继续发射“数据”事件,将流切换到流动模式。

    简单来说,当端口关闭时,串口库会发出一个关闭事件

    serialport.on('close', function(error){
      if(error.disconnected === true){
        console.log("disconnected");
     }
    } 
    

    ,这将让我们知道端口是否断开。

    这意味着断开的端口无法重新建立连接,因此您必须使用 serialport.resume() 方法重新启用连接。

    serialport.on('close', function(err){
      console.log("Port closed.");
      if(err.disconnected === true){
        console.log("Disconnected!");
        serialport.resume(function(e){
          reconnectDevice(); // Serial Port Initialization Function. It's your method to declare serial port.
          console.log("Error on resuming port:", e);
        });
      }
    });
    

    之后,它会自动切换 COM 端口,不会出现“端口访问被拒绝”的错误。

    【讨论】:

      猜你喜欢
      • 2016-02-08
      • 2016-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-05
      • 1970-01-01
      • 2018-02-16
      • 1970-01-01
      相关资源
      最近更新 更多