Отправка JSON из Python в Node через child_process усекается, если слишком долго, как это исправить? - PullRequest
0 голосов
/ 10 июня 2018

Мой Node & Python backend работает нормально, но теперь я столкнулся с проблемой, когда если JSON, который я отправляю с Python обратно, Node слишком длинный, он разделяется на два, и мой JSON.parse на стороне Nodeне удается.

Как это исправить?Например, первый пакетный клип на

... [1137.6962355826706, -100.78015825640887], [773.3834338399517, -198

, а второй содержит оставшиеся несколько записей

.201506231888], [-87276.575065248, -60597.8827676457], [793.1850250453127, 
-192.1674702207991], [1139.4465453979683, -100.56741252031816], 
[780.498416769341, -196.04064849430705]]}

Нужно ли создавать некоторую логику на стороне узла для длинных JSON илиэто какая-то проблема с буферизацией на моей стороне Python, которую я могу решить с помощью правильных настроек?Вот все, что я делаю на стороне питона:

outPoints, _ = cv2.projectPoints(inPoints, np.asarray(rvec), 
np.asarray(tvec), np.asarray(camera_matrix), np.asarray(dist_coeffs))

# flatten the output to get rid of double brackets per result before JSONifying
flattened = [val for sublist in outPoints for val in sublist]
print(json.dumps({'testdata':np.asarray(flattened).tolist()}))
sys.stdout.flush()

А на стороне узла:

// Handle python data from print() function
  pythonProcess.stdout.on('data', function (data){

    try {
      // If JSON handle the data
      console.log(JSON.parse(data.toString()));
    } catch (e) {
      // Otherwise treat as a log entry
      console.log(data.toString());
    }
  });

1 Ответ

0 голосов
/ 10 июня 2018

Излучаемые данные разбиваются на части, поэтому, если вы хотите проанализировать JSON, вам нужно объединить все куски, и на end выполнить JSON.parse.

По умолчаниюканалы для stdin, stdout и stderr устанавливаются между родительским процессом Node.js и порожденным потомком.Эти трубы имеют ограниченную (и зависящую от платформы) пропускную способность.Если дочерний процесс записывает в стандартный вывод, превышающий этот предел, без захвата выходных данных, дочерний процесс блокирует ожидание, пока буфер канала не примет больше данных.

In linux каждый блок ограничен 65536 байтами.

В версиях Linux до 2.6.11 емкость канала была такой же, как размер системной страницы (например, 4096 байт на i386).Начиная с Linux 2.6.11 емкость канала составляет 65536 байт.

let result = '';
pythonProcess.stdout.on('data', data => {
    result += data.toString();
    // Or Buffer.concat if you prefer.
});

pythonProcess.stdout.on('end', () => {
    try {
      // If JSON handle the data
      console.log(JSON.parse(result));
    } catch (e) {
      // Otherwise treat as a log entry
      console.log(result);
    }
});
...