Как предотвратить повторные ответы с сервера Node.js.
Мы столкнулись с проблемой, когда мы получаем несколько ответов, отправленных с нашего Node-сервера веб-клиенту, который подключен через сокет-сервер (socket.io). Прослушивая с помощью Docklight, я вижу, что мы действительно получаем только один ответ от последовательного устройства, но по какой-то причине сервер Node отправляет кратные числа, и они накапливаются, поэтому при первой отправке последовательной команды (и ее не имеет значения, какие команды) может получить только пару, в следующий раз еще пару, в следующий раз еще пару и так далее. Так что, если вы запустите несколько последовательных команд, вы получите много разных ответов.
Наша среда - 64-битная Windows 7, Node V 4.5.0, serialport V 4.0.1. Тем не менее, это должно работать на Windows, Mac и Linux, когда мы закончим. Команда разработчиков (я и еще один парень) - новички в Node, но в остальном способные разработчики.
Я думаю, что происходит, я не использую .flush()
& .drain()
функционирует должным образом, и буфер последовательного порта все еще содержит последовательные данные. Наши фирменные устройства возвращают либо S>
, или же <Executed/>
выдает запрос о завершении команды, поэтому я сохраняю последовательный ответ в буфере до тех пор, пока не увижу одно или другое, затем обрабатываю данные (в этом примере просто предоставляем логический ответ независимо от того, отвечает устройство одно или другое или нет), Например, если я отправлю <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: