简体   繁体   English

如何将非常大的图像从 python 脚本传输到 NodeJS 而不会导致节点应用程序(电子)中的延迟

[英]How to transfer very large images from a python script to NodeJS without causing lag within the node app (electron)

I am working on a project that involves grabbing pictures from a python script (the python is interacting with a camera by calling c functions).我正在从事一个项目,该项目涉及从 python 脚本中抓取图片(python 通过调用 c 函数与相机交互)。 The issue I am currently having is that sending images using socket.io to the javascript app is causing massive lag when the message is first received (about a 3-second pause).我目前遇到的问题是,当第一次收到消息时,使用 socket.io 将图像发送到 javascript 应用程序会导致大量延迟(大约 3 秒的暂停)。 The images are around 15mb each and are in png format when sent.每个图像大约 15mb,发送时为 png 格式。 What is the most efficient way to transfer these images from the python script to the node-js app with no or very very little lag (not lag in sending but lag in the app when receiving)?将这些图像从 python 脚本传输到 node-js 应用程序的最有效方法是什么,没有延迟或延迟很小(不是发送延迟,而是接收时应用程序延迟)? The way I am currently handling this is like so:我目前处理这个的方式是这样的:

socket.on("frame", data => {});

Even when doing nothing with the data that is received, the app still lags/freezes for 3 seconds.即使对接收到的数据不做任何处理,应用程序仍然会延迟/冻结 3 秒。 The python script and electron app will likely be housed on the same machine if that helps...如果有帮助的话,python 脚本和电子应用程序可能会安装在同一台机器上......

First off, make sure socket.io is operating in binary mode so you're not encoding the image data in any way that could make it a lot larger or make the transmission a lot slower to process.首先,确保 socket.io 以binary模式运行,这样您就不会以任何可能使其变大或使传输处理速度变慢的方式对图像数据进行编码。

Then, see if you can get any information about the CPU usage from both the Python and the JS processes during a transfer to see if one or the other is overly hogging the CPU.然后,查看在传输期间是否可以从 Python 和 JS 进程中获取有关 CPU 使用率的任何信息,以查看其中一个进程是否过度占用 CPU。 Properly done I/O code in node.js should be entirely event driven and (if you aren't doing any time consuming processing of the incoming data) should not take much CPU just to read bytes from a socket. node.js 中正确完成的 I/O 代码应该完全是事件驱动的,并且(如果您没有对传入的数据进行任何耗时的处理)不应该仅仅从套接字读取字节就占用太多 CPU。

You asked me to post the code for my test app that sends a 65MB image in 106ms.你让我发布我的测试应用程序的代码,它在 106 毫秒内发送一个 65MB 的图像。 So, here it is.所以,在这里。 It's two apps, one that sends and one that listens for incoming TCP connections and receives.这是两个应用程序,一个发送,一个侦听传入的 TCP 连接并接收。 The sending app, takes a filename as a command line parameter.发送应用程序将文件名作为命令行参数。 All it does is make a connection to the local server and send the entire file to the server, then shut-down.它所做的只是连接到本地服务器并将整个文件发送到服务器,然后关闭。 So, each TCP connection is for one file.因此,每个 TCP 连接都针对一个文件。 There's minimal error handling as this was just a test harness.由于这只是一个测试工具,因此错误处理最少。

Here's the sending app:这是发送应用程序:

const net = require('net');
const process = require('process');
const fs = require('fs');

let imgFile = process.argv[2];

const port = 3000;
const host = "localhost";

const socket = net.connect(port, host, () => {
    console.log(`connect to ${host} on ${port} succeeded`);
    const stream = fs.createReadStream(imgFile);
    let cnt = 0;
    stream.on('data', (buffer) => {
        cnt += buffer.length;
        if (!socket.write(buffer)) {
            stream.pause();
            socket.once('drain', () => {
                stream.resume();
            });
        }
    }).on('error', (err) => {
        console.log(err);
    }).on('end', () => {
        console.log(`image sent ${cnt} bytes, ${Math.round(cnt/1024)}KB`);
        socket.end();
    });
});

And, here's the receiving app:而且,这是接收应用程序:

const net = require('net');

let server = net.createServer(socket => {
    let start = Date.now();
    let cnt = 0;
    console.log("received connection")
    // socket.setEncoding('binary');
    socket.on('data', buffer => {
        // do nothing with the data
        cnt += buffer.length;
    }).on('end', () => {
        console.log(`got ${cnt} bytes, ${Math.round(cnt/1024)}KB`);
        console.log(`Took ${Date.now() - start} ms` )
    }).on('error', e => {
        console.log(e);
    });
});

server.listen(3000);

Both apps are just sending and receiving binary data (no encoding involved).这两个应用程序都只是发送和接收二进制数据(不涉及编码)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM