使用fork的子进程传递和访问请求响应对象
我想知道如何使用fork将父进程的请求响应对象传递给子进程。 我所做的是使用fork的子进程传递和访问请求响应对象
var child = cp.fork(__dirname + '/childProcess.js', req, res);
child.on('message', function(m)
{
console.log("child process returned data " + m);
});
child.send("hello");
childProcess.js
var req = process.argv[2];
var res = process.argv[3];
process.on('message', (msg) =>
{
console.log("req object :-" + req);
console.log("res object :-" + res);
}
process.send("callparent");
这使我在子进程不确定。我也尝试过child.send(“hello”,req.socket)。但后来我无法访问子进程中的请求方法。它显示为圆形结构。
按照docs:
child.send(消息[,sendHandle] [,回调])
其可以被传递给
child.send()
可选sendHandle
参数是用于使TCP服务器或套接字对象到子进程。子对象将作为第二个参数传递给在process.on('message')
事件中注册的回调函数。
这表明,你应该在child.send()
功能发送req
或req.socket
对象。
另外,您没有从登录到process.on('message')
事件的函数的第二个参数访问req
或req.socket
对象。
您创建一个服务器,并向客户端发送句柄。 如果使用快递例如,你可以这样做:
Server.js
child= require('child_process').fork('child.js');
const server = require('net').createServer();
server.on('connection', function(socket) {
child.send('handle', socket);
}).listen(80);
然后创建一个孩子,并接受手柄:
Child.js
var app=require('express')()
app.get('/',function(req,res){
console.log(req.headers)
res.send('Working!')
})
var myServer=require('http').createServer(app)
process.on('message', function(m, server) {
if (m === 'handle') myServer.listen(handle)
});
更多信息:
其他的答案告诉你套接字发送到儿童和有孩子听和处理请求,这不是被问到的问题(如何将req/res发送给孩子)。如果您的目标是将套接字传递给孩子并让孩子监听并处理请求,那么这些答案都可以。如果您的目标是在主流程中侦听并预处理请求,并将这些请求传递给子进程以供进一步处理,请参阅:
简而言之,您必须实际明确发送请求并回应孩子的过程(他们不会神奇地出现在孩子的过程中)。但是有一些挑战。
在我们的应用程序中,我们有类似的问题。我们的主请求处理器检查请求以查看哪个子进程应该处理每个请求,然后将该请求发送给子进程(通过child.send()
)。
在父和子之间传递请求/响应的问题是您必须能够序列化与send
来回发送的对象,并且特别是请求对象不能被序列化(它充满了循环引用,引用许多其他对象等)。
因此,我们所做的是将数据的子集拉出子进程需要的请求,并且我们通过child.send()
将该“轻量级请求”对象发送给子进程,同时保留对原始请求的引用队列在父进程上。当子进程完成处理时,它通过parent.send()
将其响应数据发送回父节点,并且父节点与未决队列中原始请求一起匹配,并使用响应数据满足请求。
这种方法的优点(与在父/子之间创建自定义协议相反)是子请求处理代码仍然在请求/响应对象(只是它们的轻量级版本)上运行。在我们的例子中,这意味着我们可以使用相同的请求处理代码,不管我们是在子进程中调用它,还是让进程直接监听和处理请求。
例如,下面是如何使一个轻量级的,序列化的请求对象并将其发送到子进程:
var requestData =
{
httpVersion: request.httpVersion,
httpVersionMajor: request.httpVersionMajor,
httpVersionMinor: request.httpVersionMinor,
method: request.method,
url: request.url,
headers: request.headers,
body: request.body
}
child.send(requestData);
你也可以只使用像lodash pick东西抓住你想要的字段。
这个解决方案的一个棘手部分是,如果您需要调用请求/响应的任何方法,您必须在父对象(实际对象所在的位置 - 所有子对象都是选定数据)中执行此操作。
知道您在父进程的队列中保留对原始请求的引用会很有趣。 –
我们使用我们自己的异步操作管理器实现来保存完成状态(并处理超时)。这里是代码(开源,随意使用): https://github.com/SynchroLabs/SynchroServer/blob/master/SynchroServer/node_modules/synchro-api/lib/async-ops-mgr.js 如果您对我们如何使用该产品感兴趣,请参阅: https://github.com/SynchroLabs/SynchroServer/blob/master/SynchroServer/node_modules/synchro-api/lib/api-request-delegator.js# L154 如果有人想要,我很乐意将npm模块制作出来。 – BobDickinson
感谢您的建议..我做了你说的话,但我怎么能访问REQ Res对象在子进程..另外我想要request.headers在子进程。你知道如何去做吗? –
定期像任何明确的应用程序。 'app.get('/',function(req,res){})'。关于请求标题,你可以在不同的问题中提问:)你可以使用req.headers来获取它。 – Aminadav
编辑和添加有关res,res和标题的信息 – Aminadav