nodejs-serialport => 关闭后重新建立到端口的连接
nodejs-serialport => RE-Establish connection to port after closed
根据我的上一个问题 。我无法检测到 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_modules/serialport/lib/serialport.js
中所见:close
-事件可能不会发出(与 disconnect
不同)。
您可以像下面这样在本地添加 console.log
以进行简单调试。
P.S。我在 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
根据 serialport.io、
The resume() method causes an explicitly paused, Readable stream to
resume emitting 'data' events, switching the stream into flowing mode.
简单地说,当端口关闭时,串口库会发出一个关闭事件
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 端口,您不会像 'Port Access denied.' 那样出现错误。
根据我的上一个问题 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_modules/serialport/lib/serialport.js
中所见:close
-事件可能不会发出(与 disconnect
不同)。
您可以像下面这样在本地添加 console.log
以进行简单调试。
P.S。我在 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
根据 serialport.io、
The resume() method causes an explicitly paused, Readable stream to resume emitting 'data' events, switching the stream into flowing mode.
简单地说,当端口关闭时,串口库会发出一个关闭事件
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 端口,您不会像 'Port Access denied.' 那样出现错误。