我正在使用node.js构建一个系统,用户可以从Web界面生成工作进程,而我在系统中将这两个标准组合起来时遇到了问题:
我已经能够自己完成这两个标准,但不能一起完成。以下是我的代码目前的相关部分:
function spawnWorker (id, callback) {
var worker = spawn("node", [require.resolve("worker"), id], {
detached: true,
stdio: ["ignore", "pipe", "pipe"]
});
worker.unref();
var logfile = fs.createWriteStream("foo.log");
worker.stdout.once("data", function (data) {
worker.stdout.pipe(logfile);
worker.stderr.pipe(logfile);
callback(undefined, data.toString());
});
}
这符合条件2(即,它接收来自worker的第一条消息,并将所有后续输出重定向到文件),但是如果我杀死了母进程,则即使输出已被删除,也会终止工作进程重定向。
我的猜测是,这是因为工作人员的stdout和stderr在被发送到文件流之前被传送到母进程。如果我在生成进程时传入流,根据docs,节点将在工作进程中复制该流:
流的基础文件描述符在子进程[...]
中重复
有没有办法在收到第一条消息后删除母进程和工作进程之间的连接?或者我应该使用某种类型的RPC来实现这一点,如果是这样,一旦通信,这对一条消息会有什么好的选择?
答案 0 :(得分:0)
我使用节点的net
模块解决了这个问题,在一个随机端口上生成服务器,该服务器在启动时传递给工作人员(因此它知道在准备就绪时将响应发送到哪里)。
以下是我的解决方案的实施示例,澄清一下,这符合以下要求:
server.js
var net = require("net"),
fs = require("fs"),
spawn = require("child_process").spawn,
randomPort = require("get-port");
randomPort(function (port) {
var server = net.createServer(function (connection) {
connection.on("data", function (data) {
server.close();
/**
* Response received from worker, this is where you would put
* your logic that returns a response to the client that initiated
* the request to the server.
*/
});
});
server.listen(port);
var logfile = fs.createWriteStream("log");
var worker = spawn("node", ["worker.js", port], {
detached: true,
stdio: ["ignore", logfile, logfile]
});
worker.unref();
worker.on("close", function (status, message) {
console.log("worker closed", status, message);
});
});
worker.js
var net = require("net");
var options = process.argv.slice(2),
rpcPort = Number(options[1]);
var client = net.connect({port: rpcPort}, function () {
client.end(JSON.stringify({started: true}}));
});