I'm building a NodeJS server with ExpressJS that processes data (50KB to >100MB) sent via POST request from a desktop app to be processed and returned. The desktop app gzip compresses the data prior to sending (50KB becomes 4KB).
I want the server to decompress the data, extract the values from the data (strings, integers, chars, arrays, json, etc), process that data, and then respond with the processed data.
I started with this:
apiRoute.route("/convert").post(bodyParser.raw({limit: '100Mb'}), (req, res) =>{
let outputData;
//extract values from req.body Buffer and do math on them.
//save processed data in outputData
res.json({
status: true,
data: outputData
});
});
This works because body-parser decompresses the data into a Buffer req.body
stored in memory. That is my main issue... memory usage. I do not want to store the entire dataset in memory.
To resolve this I removed body-parser and instead piped the request stream directly into a zlib transform stream:
apiRoute.route("/convert").post((req, res) =>{
req.pipe(zlib.createGunzip());
});
The issue now is that I don't know how to extract binary values from the stream.
This is what I would LIKE to be able to do:
apiRoute.route("/convert").post((req, res) =>{
let binaryStream = new stream.Transform();
req
.pipe(zlib.createGunzip())
.pipe(binaryStream);
let aValue = binaryStream.getBytes(20);//returns 20 bytes
let bValue = binaryStream.getBytes(20000);//returns the next 20000 bytes
//etc...
});
However I don't know of any way to accomplish this. Modules like Dissolve are close, however they require you to set up the parsing logic ahead of time and all the grabbed values are stored in memory.
Plus I don't know how to respond with the outputData without also loading it all into memory.
So my question is, how do I...
- Read the data from the stream at my own rate asynchronously and extract the values within
- Send the processed data back to the desktop app without putting it all in memory