Возможно ли в Node дождаться успеха/ошибки операции net.socket перед отправкой экспресс-ответа?Javascript

Форум по Javascript
Ответить
Anonymous
 Возможно ли в Node дождаться успеха/ошибки операции net.socket перед отправкой экспресс-ответа?

Сообщение Anonymous »

Прошу прощения, если это невозможно, нецелесообразно или ответили где-то еще, но я потратил пару дней, пытаясь найти ответ, а также изменяя/тестируя код всеми возможными способами, но не добился желаемого результата.
У меня есть внутреннее веб-приложение, написанное на Node, с конечной точкой API (Express), которое вызывает функцию для отправки данных на принтер через сетевой сокет. Сам код работает (в том, что касается выборки, вызова функций и соединения с сокетом), и мы используем тот же поток/функциональность в других приложениях. Тем не менее, я пытаюсь сделать так, чтобы конечная точка Express API ждала отправки своего ответа до тех пор, пока не будет установлено подключение к сетевому сокету или не произойдет ошибка, чтобы ответ мог быть соответствующим (5xx для ошибки, 2xx для успешного подключения к сокету). Это связано с тем, что пока код работает, иногда принтер находится в состоянии ошибки и время ожидания соединения с сокетом истекает, но экспресс-ответ всегда является «успешным», поскольку вызов функции успешен.
Мой желаемый поток таков: клиентский браузер выполняет вызов выборки в конечную точку; конечная точка принимает данные req.body и вызывает функцию печати; функция печати пытается подключиться к принтеру через сокет и возвращает конечной точке либо true, либо false (если сокет подключается или возникает ошибка); затем конечная точка, дождавшись возврата, отправляет res.status(...).send(...) с правильным кодом и данными ответа (JSON), чтобы клиентский браузер мог отобразить соответствующее сообщение об успехе или неудаче.
Ниже приведены фрагменты кода, используемые в этом потоке, с некоторыми деталями, измененными в целях конфиденциальности. Эта версия кода представляет собой исходный «рабочий» набор, не включающий в себя ничего дикого/странного, что я пробовал за последние пару дней. В других версиях тестирования я пробовал использовать async/await, обертку с помощью обещания и т. д., но независимо от того, что я делаю, функция sendToPrinter всегда возвращает true до подключения сокета или возникновения ошибки, о чем свидетельствует порядок вывода console.logs.
Любые советы, предложения, рекомендации или исправления приветствуются! И, пожалуйста, не говорите мне, что это плохая практика и т. д., это специальное внутреннее приложение для конкретной задачи в промышленных условиях. Меня интересует только то, возможна ли вообще моя желаемая функциональность и как это сделать.
/* 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'
}
});
});

/* 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;
};


Подробнее здесь: https://stackoverflow.com/questions/798 ... peration-b
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»