#python #sockets #socket.io #timeout #emit
Вопрос:
Я хочу создать функцию, которую экспресс-сервер будет выдавать клиенту (python), а python что-то сделает и выдаст результат обратно на сервер. Сервер будет ждать результата, выданного клиентом, и вернет этот результат интерфейсу. Если через некоторое время python все еще что-то не выдаст, экспресс-сервер сообщит интерфейсу, что результат не получен. Могу ли я использовать обещание и установить тайм-аут для ожидания сообщения об отправке от python?
Комментарии:
1. Привет и добро пожаловать в SO ! Пожалуйста, включите какой-нибудь код о том, что вы уже пробовали !
Ответ №1:
Это не должно быть большой проблемой. См.Подтверждения в сокете.документы ввода-вывода. У них даже есть пример для тайм-аута :
// express server endpoint
app.get('/somethingcool', (req, res) => {
// assuming socket will be the client socket of the python server
socket.emit("do_something_i_will_wait", {/* data */}, withTimeout((response) => {
console.log("success!");
res.status(200).send(response);
}, () => {
console.log("timeout!");
res.status(500).send("python took to long to reply");
}, 5000));
});
// helper function for timeout functionality
const withTimeout = (onSuccess, onTimeout, timeout) => {
let called = false;
const timer = setTimeout(() => {
if (called) return;
called = true;
onTimeout();
}, timeout);
return (...args) => {
if (called) return;
called = true;
clearTimeout(timer);
onSuccess.apply(this, args);
}
}
Как работают подтверждения
Поэтому мы передаем что — то от сервера клиенту, что-то простое, и в качестве последнего аргумента мы поставим функцию-это будет наша функция подтверждения.
// server
socket.emit("ferret", "tobi", (data_from_client) => {
console.log(data_from_client); // data will be "woot"
});
На стороне клиента это будет выглядеть примерно так. Обратный вызов, который мы устанавливаем для прослушивателя событий «хорек», принимает 2 аргумента, данные, которые мы передаем с сервера клиенту, и нашу функцию подтверждения.
// client
client.on("ferret", (name, fn) => {
fn("woot");
});
Более простой пример
Я понимаю, что withTimeout
пример из сокета.документы ввода-вывода могут быть немного сложными для понимания, поэтому приведем менее сложный пример, который в основном делает то же самое :
app.get('/somethingcool', (req, res) => {
let got_reply = false;
const timeout = setTimeout(() => {
if (got_reply) { return; }
got_reply = true;
res.status(500).send("too late");
}, 5000);
socket.emit("do_something_i_will_wait", {}, (reply) => {
if (got_reply) { return };
got_reply = true;
clearTimeout(timeout);
res.status(200).send(reply);
});
});
Комментарии:
1. Большое вам спасибо! это выглядит многообещающе! намеренный каламбур!
2. Так, скажем, клиентский сокет будет выдавать sth обратно на сервер. Где я должен поместить socket.on(«ответ от python», данные=> данные))?
3. В этом нет необходимости
Acknowledgments
. Если выemit
«do_something_i_will_wait», вы также передаете функцию, которая используется в качестве подтверждения. Эта функция подтверждения вызывается, когда клиент отвечает. Нет необходимости добавлять дополнительного слушателя только для ответа. Я добавлю пример того, как это будет выглядеть на стороне клиента.