Nodejs 和 Express,使用来自工作线程的 res.send()
Posted
技术标签:
【中文标题】Nodejs 和 Express,使用来自工作线程的 res.send()【英文标题】:Nodejs and Express, use res.send() from a worker thread 【发布时间】:2020-02-25 22:01:30 【问题描述】:在 Nodejs 中,使用 Express 作为服务器,我将繁重的计算卸载到工作线程上。
在主应用程序中,我这样调用工作线程:
// file: main.js
const Worker = require("worker_threads");
function runService(fileName, workerData)
return new Promise((resolve, reject) =>
const worker = new Worker(fileName, workerData );
worker.on("message", resolve);
worker.on("error", reject);
worker.on("exit", code =>
if (code !== 0)
reject(new Error(`Worker stopped with exit code $code`));
);
);
router.get("/some_url", async function(req, res)
const result = await runService(
"./path/to/worker.js",
query: req.query, user: req.user // using req causes an error
);
);
工人看起来像这样:
// file: worker.js
const workerData, parentPort = require('worker_threads');
const query, user = workerData;
async function run()
const result = await generateLotsOfData(query, user);
parentPort.postMessage(result);
// What I would like to do here (doesn't work): res.send(result);
worker 生成大量数据,“postMessage”导致服务器错误。
有没有办法使用res.send()
或类似的方法将这些数据从工作线程直接发送到客户端?
(而不是使用postMessage
,然后从主线程发送)?
【问题讨论】:
流有帮助吗? 不确定您的确切用例,但您应该能够使用 res.write() 流式传输值,如下所示:gist.github.com/montanaflynn/6a438f0be606daede899 我仍然需要将数据从工作线程发送到主线程,然后才能使用 res.write()。 Streams 可能仍然有用,因为我必须每次发送 Les 数据。 您找到解决方案了吗@HendrikJan?我面临着类似的问题。 @lukas1994 我没有找到直接从工作线程发送的方法。请参阅我的回答,了解我最终如何解决我的问题。 【参考方案1】:似乎无法直接从 worker-tread 发送到客户端。 最后,我使用了子进程(而不是工作线程),并将结果发送回主线程,然后发送给客户端。
// file: main.js
var child_process = require('child_process');
// Run a worker thread
function runService(fileName, workerData)
return new Promise((resolve, reject) =>
const worker = child_process.fork(fileName);
worker.on('message', function(message)
if (message.ready)
// worker is ready to receive data
worker.send(workerData);
else
// worker finished it's calculations, send the data to the client
resolve(message);
);
worker.on("error", function(x)
console.log('error', x);
resolve(status: 500);
);
worker.on("close", function(y)
console.log('close', y);
);
worker.on("exit", function(code)
if (code == 0)
console.log('report ran successfully');
else
console.log('report FAILED');
resolve(status: 500);
);
);
在工人中:
process.on('message', run);
process.send(ready: true);
async function run(workerData)
try
const result = doSomeCalculations();
process.send(
data: JSON.stringify(result)
, null, , function() process.exit(0));
catch(err)
console.error(err);
process.exit(1); // exit the process with a failure
// Make sure that this child_process doesn't accidentally stay in memory.
// Kill after 10 minutes. (not sure this is necessary, just to be sure)
setTimeout(function()
console.log('Timeout in child-process');
process.exit(1);
, 600000);
这实际上效果很好。
【讨论】:
以上是关于Nodejs 和 Express,使用来自工作线程的 res.send()的主要内容,如果未能解决你的问题,请参考以下文章