我们遇到了一个问题,我们从我们的 Node 服务器收到多个响应发送到由套接字服务器 (socket.io) 连接的 Web 客户端。通过使用 Docklight 进行监听,我可以看到我们实际上只从串行设备获得了一个响应,但由于某种原因,Node 服务器正在发送多个响应,并且它们会累积,所以当你第一次发送串行命令时(它不管什么命令)可能只会得到几个,下一次更多,下一次更多,依此类推。因此,如果您运行多个串行命令,您将得到很多多个响应。
我们的环境是 Windows 7 64 位,Node V 4.5.0,serialport V 4.0.1。但是,当我们完成后,这需要在 Windows、Mac 和 Linux 上运行。开发团队(我和另外一个人)对 Node 来说都是相当新的,但在其他方面都是有能力的开发人员。
我认为发生的事情是我没有正确使用.flush()
&.drain()
函数,并且串行端口缓冲区仍然包含串行数据。我们的专有设备在命令完成时返回S>
或<Executed/>
提示,因此我将串行响应存储在缓冲区中,直到看到其中一个,然后处理数据(在此示例中,仅提供布尔响应,无论设备是否响应一个或另一个或不是)。例如,如果我将 a 发送<CR><LF>
到我们的一个设备,它应该响应S>
(或<Executed/>
依赖)。
客户端通过以下方式调用服务器:
socket.on('getDeviceConnected', readDeviceResponse);
function readDeviceResponse(isDeviceResponding) {
console.log('getDeviceConnected');
console.log(isDeviceResponding);
}
function getDeviceConnected() {
console.log("Sending carriage return / line feed.");
socket.emit('getDeviceConnected', '\r\n');
}
在服务器上,这就是我正在尝试的:
socket.on('getDeviceConnected', function (connectionData) {
//write over serial buffer before the write occurs to prevent command accumulation in the buffer.
serialBuffer = '';
sbeSerialPort.write(connectionData, function (err, results) {
//since there's no way to tell if the serial device hasn't responded, set a time out to return a false after allowing one second to elapse
setTimeout(function () {
console.log('Inside getDeviceConnected setTimeout');
console.log('Is serial device responding:', isSerialDeviceResponding);
if (!isSerialDeviceResponding) {
console.log('Serial device timed out.');
socket.emit('getDeviceConnected', false);
}
}, 1000);
if (err) {
console.log('Serial port error level:', err);
}
if (results) {
if (results === 2) {
console.log('Serial port is responding');
}
}
});
sbeSerialPort.on('data', function (serialData) {
isSerialDeviceResponding = true;
console.log('Does S> prompt exist?', serialData.lastIndexOf('S>'));
while(!serialData.lastIndexOf('S>') > -1 || !serialData.lastIndexOf('<Executed/>') > -1){
serialBuffer += serialData;
break;
}
if (isSerialDeviceResponding) {
socket.emit('getDeviceConnected', true);
isSerialDeviceResponding = true;
}
sbeSerialPort.flush(function (err, results) {
if (err) {
console.log(err);
return;
}
if(results){
console.log('Serial port flush return code:', results);
}
});
});
我不太确定.flush()
这里的实现,我省略了这.drain()
部分,因为它们似乎都没有做很多事情(假设它们被正确实现)。
.write()
当命令完成时,如何确保串口缓冲区中没有数据?或者您是否看到我处理串行数据的其他问题?
编辑,pastebin.com 上的源代码: