简体   繁体   中英

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). 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). The images are around 15mb each and are in png format when sent. 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)? 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. The python script and electron app will likely be housed on the same machine if that helps...

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.

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. 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.

You asked me to post the code for my test app that sends a 65MB image in 106ms. So, here it is. It's two apps, one that sends and one that listens for incoming TCP connections and receives. 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. 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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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