2017-08-11 3 views
-1

Ich baue eine Barcode-Scan-App mit dem Knoten-Serialport. Wo ich feststecke, mache ich einen AJAX-Anruf, um einen Scan auszulösen und Express-Server mit den Daten aus dem lesbaren Stream reagieren zu lassen.Pause Node.js Lesbarer Stream

initialisieren Device:

// Open device port  
var SerialPort = require('serialport'); 
var port = '/dev/cu.usbmodem1411'; 
var portObj = new SerialPort(port, (err) => { 
if(err) { 
    console.log('Connection error ' + err); 
} 
}); 

//Construct device object 
var Scanner = { 
    // Trigger Scan 
    scan :() => { 
    portObj.write(<scan cmd>), (err) => { 
     if(err) { 
     console.log('Error on scan' + err); 
     } 
    }); 
    } 
} 

Ich habe versucht, zwei Ansätze und weder produzieren das Verhalten 'Scan-read-Respond' ich suche.

Zuerst habe ich versucht, einen Ereignis-Listener unmittelbar nach einem Scan zu setzen und dann einen Callback im Listener zu verwenden, um auf die AJAX-Anfrage zu antworten. Mit diesem Ansatz bekomme ich einen 'Kann Header nicht setzen, nachdem sie gesendet werden' Fehler '. Soweit ich weiß, wirft Node diesen Fehler, weil res.send mehrfach aufgerufen wird.

erste Ansatz - Antwort als Callback in Zuhörer:

app.get('/dashboard', (req, res) => { 
Scanner.scan(); //fire scanner 
portObj.on('data', (data) => { 
    res.send(data); //'Can't set headers after they are sent' error' 
}); 
} 

Im zweiten Ansatz, speichere ich die Scandaten in eine lokale Variable (‚scanned_data‘) und die Reaktion außerhalb des Zuhörers Block bewegen. Das Problem bei diesem Ansatz besteht darin, dass res.send ausgeführt wird, bevor die gescannten Daten in der lokalen Variablen erfasst werden, und daher als "undefiniert" angezeigt wird. Interessant ist auch, dass die gescannten Daten, die im Listener-Block erfasst werden, bei jedem Scan mehrfach vorkommen.

Zweite Ansatz - Antwort außerhalb Zuhörer:

app.get('/dashboard', (req, res) => { 
    var scanned_data; //declare variable outside listener block 
    Scanner.scan(); //trigger scan 
    portObj.on('data', (data) => { 
    scanned_data = data; 
    console.log(scanned_data); //displays scanned data but data multiplies with each scan. (e.g. 3 triggers logs 'barcode_data barcode_data barcode_data') 
    }); 
    console.log(scanned_data); //undefined 
    res.send(scanned_data); 
} 

Ich bin ein Front-Entwickler Ende aber habe viel über Knoten versucht, dies herauszufinden, zu lernen bekommen. Ach, ich glaube, ich bin an diesem Punkt in eine Sackgasse geraten. Ich habe mit dem Befehl .pipe() gebastelt und habe eine Ahnung, wo die Lösung liegt, aber es war nicht möglich, eine funktionierende Lösung auf Null zu setzen.

Irgendwelche Gedanken oder Vorschläge?

+0

Node.js Implementierung von Streams nicht ausprobiert. Ist es erforderlich, nur die Implementierung von node.js Streams zu verwenden? Was ist das erwartete Ergebnis? – guest271314

+0

Aufgrund anderer Einschränkungen muss ich node.js für die Stream-Implementierung verwenden. Das erwartete Ergebnis besteht darin, einen Barcode unter Verwendung eines seriellen Geräts (verbunden durch Knoten-Serialport) scannen zu können und diese Daten als Antwort auf einen Ajax-Anruf zu senden. – MaxPowers

Antwort

0

Sie sollten keine Annahmen darüber treffen, welchen Datenblock Sie in einem 'data'-Ereignis erhalten. Erwarten Sie ein Byte oder viele Bytes. Sie müssen wissen, welches Protokoll verwendet wird, um zu wissen, wann Sie eine vollständige "Nachricht" erhalten haben, damit Sie nicht mehr auf Daten warten müssen. Zu diesem Zeitpunkt sollten Sie eine Antwort auf die HTTP-Anfrage senden.

+0

Ich denke, der Datenblock im lesbaren Stream besteht aus vielen Datenbytes, weshalb die Daten mit der Anzahl der Scans multipliziert werden. Ich dachte daran, die Chunk-Größe zu begrenzen, aber das könnte mit anderen Features auf der Straße kollidieren, die mit größeren Brocken antworten. Irgendeine Idee darüber, wie ich feststellen kann, wann die vollständige Nachricht empfangen wurde und Knoten aufhören, auf Daten zu hören? – MaxPowers