Ich habe eine interne Webanwendung in Node mit einem API-Endpunkt (Express) geschrieben, die eine Funktion aufruft, um Daten über einen Net-Socket an einen Drucker zu senden. Der Code selbst funktioniert (was Abruf, Funktionsaufruf und Socket-Verbindung betrifft) und wir verwenden denselben Ablauf/dieselbe Funktionalität in anderen Anwendungen. Ich versuche es jedoch so zu gestalten, dass der Express-API-Endpunkt mit dem Senden seiner Antwort wartet, bis die Net-Socket-Verbindung entweder hergestellt wurde oder Fehler aufgetreten sind, damit die Antwort angemessen sein kann (5xx für Fehler, 2xx für erfolgreiche Socket-Verbindung). Dies liegt daran, dass der Code zwar funktioniert, sich der Drucker jedoch manchmal in einem Fehlerzustand befindet und die Socket-Verbindung abläuft, die Express-Antwort jedoch immer „Erfolg“ lautet, da der Funktionsaufruf erfolgreich ist.
Mein gewünschter Ablauf ist dieser: Der Client-Browser führt einen Abrufaufruf an den Endpunkt durch; Der Endpunkt nimmt die req.body-Daten und ruft die Druckfunktion auf. Die Druckfunktion versucht, eine Socket-Verbindung zum Drucker herzustellen und gibt entweder „true“ oder „false“ an den Endpunkt zurück (wenn der Socket eine Verbindung herstellt oder Fehler auftritt). Nachdem der Endpunkt auf die Rückgabe gewartet hat, sendet er dann ein res.status(...).send(...) mit korrektem Code und Antwortdaten (JSON), damit der Client-Browser die entsprechende Meldung über Erfolg oder Misserfolg anzeigen kann.
Unten sind die in diesem Ablauf verwendeten Codeausschnitte aufgeführt, wobei einige Details aus Datenschutzgründen geändert wurden. Diese Version des Codes ist der ursprüngliche „Arbeits“-Satz, ohne die wilden/seltsamen Dinge, die ich in den letzten paar Tagen ausprobiert habe. In anderen Testversionen habe ich versucht, async/await zu verwenden, mit einem Versprechen zu umschließen usw., aber egal, was ich mache, die sendToPrinter-Funktion gibt immer true zurück, bevor der Socket eine Verbindung herstellt oder Fehler auftritt, wobei die Ausgabereihenfolge von console.logs dies anzeigt.
Alle Tipps, Vorschläge, Ratschläge oder Korrekturen sind willkommen! Und sagen Sie mir bitte nicht einfach, dass dies eine schlechte Praxis usw. ist, es handelt sich um eine benutzerdefinierte interne Anwendung für eine bestimmte Aufgabe in einem industriellen Umfeld. Mich interessiert nur, ob meine gewünschte Funktionalität überhaupt möglich ist und wie ich sie umsetzen kann.
Code: Select all
/* router.js */
import express from 'express';
import { printKit } from './controller.js';
const api = express.Router();
export default api;
api.post('/printKit/', (req, res, next) => {
if (printKit(req.body.lotNumber, req.body.expirationDate, req.body.printer)) res.send({
'success': true,
'message': 'Successful print',
'lotNumber': req.body.lotNumber,
'expirationDate': req.body.expirationDate,
'printer': {
'host': (req.body.printer) ? req.body.printer.host || 'default' : 'default',
'port': (req.body.printer) ? req.body.printer.port || 'default' : 'default'
}
});
else res.status(500).send({
'success': false,
'message': 'Issue sending print',
'lotNumber': req.body.lotNumber,
'expirationDate': req.body.expirationDate,
'printer': {
'host': (req.body.printer) ? req.body.printer.host || 'default' : 'default',
'port': (req.body.printer) ? req.body.printer.port || 'default' : 'default'
}
});
});
Code: Select all
/* controller.js */
import net from 'net';
export { printKit };
const defaultPrinter2x3 = {'host':'0.0.0.0', 'port':9100}; // ip changed for privacy
const printKit = (lotNumber, expirationDate, printer = defaultPrinter2x3) => {
if (!printer.host || !printer.port) printer = defaultPrinter2x3;
console.log(`\nEntry: printKit(${lotNumber},${expirationDate},{${printer.host},${printer.port}})`);
const shortExpirationDate = shortenDate(expirationDate);
const zpl = `this code removed for privacy`;
const success = sendToPrinter(printer,zpl);
if(success) return true;
else return false;
};
const sendToPrinter = (printer, zpl) => {
console.log(`\nEntry: sendToPrinter({${printer.host},${printer.port}}, ${zpl})`);
if(!printer) {
console.log('No printer host/port specified');
return false;
}
if(!printer.host || !printer.port) {
console.log('No printer host/port specified');
return false;
}
const { host, port } = printer;
const data = Buffer.from(zpl);
try {
const socket = new net.Socket();
socket.connect(printer.port, printer.host, async () => {
socket.write(data, (err) => {
if (err) {
console.error('Error connecting to printer: ', err);
throw new Error(err);
} else {
console.log('Successfully sent data to printer');
}
});
socket.end();
});
socket.on('close', () => {
console.log('Closed connection to printer');
});
socket.on('error', (err) => {
console.error('Connection error:', err.message);
throw new Error(err);
})
} catch (error) {
console.error('Error in printing:', error);
return false;
}
console.log('End of function');
return true;
};
Mobile version