Я отправляю изображение с клиента Андроид на сервер Node.js, где оно обрабатывается Python программой. Я связываю Node.js с Python программой посредством пакета или библиотеки Python-Shell из NPM. Мне нужно отправить результат обработки обратно клиенту, как ответ на запрос.
Но из-за асинхронной архитектуры Node.js, ответ отправляется сразу, не дожидаясь выпонения и завершения обработки, которая занимает где-то 30-40 секунд. В результате, Андроид клиент получает пустой ответ.
К тому же, я не могу использовать res.write() несколько раз. После того как я использовал его однажды, я полагаю, что соединение разрывается. Поэтому у меня не получается использовать res.write() или res.send() в обработчике событий. И поэтому я накапливаю все сообщения из Python программы на Node.js сервер в отдельный массив, который пытаюсь отправить, но опять же необходимо дожидаться выполнения Python программы.
Итак, как можно отправить ответ, после того как работа программы завершится и результат будет готов для отправки? Есть ли другой способ для отправки результата работы (являющийся текстом) Андроид клиенту?
Код Node.js
app.post('/', rawBody, function (req, res) {
//rawBody is a function that receives chunks of image binary and creates a req.rawBody
if (req.rawBody && req.bodyLength > 0) {
console.log("entered file writing");
var timestamp = new Date().getTime().toString();
var filename = 'Image'+timestamp+'.jpg';
fs.writeFile(filename, req.rawBody);
fs.writeFile('imagelist.txt', __dirname+ '/' + filename);
//here I create an instance of PythonShell and execution of //testfile.py starts
var pyshell = new PythonShell('testfile.py', options);
//I store in the output all the messages from Python
var output = [];
// whenever python prints any output this event is emitted
pyshell.on('message', function(message, error){
if (error) throw error;
console.log(message);
//try to write the message into response
res.write(message);
output.push(message);
});
pyshell.end(function(err) {
console.log('python finished');
//send response
res.end();
});
pyshell.on('error',function(err){
console.log(err);
});
} else {
res.send(500);
}
});
Вот как я получаю ответ на Андроид клиенте:
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Cache-Control", "no-cache");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setReadTimeout(80000);
conn.setConnectTimeout(80000);
InputStream in = new BufferedInputStream(conn.getInputStream());
BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(in));
String line = "";
StringBuilder stringBuilder = new StringBuilder();
while (true) {
line = responseStreamReader.readLine();
if (line != null) {
System.out.print("accepted new response particle " + line);
stringBuilder.append(line).append("\n");
System.out.print(stringBuilder.toString());
break;
}
}
//old version
/*while ((line = responseStreamReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
//System.out.print(stringBuilder.toString());
}*/
responseStreamReader.close();
String response = stringBuilder.toString();
System.out.println(response);
in.close();
conn.disconnect();