我遇到了Node.js进程的问题
所以我有一个父/子进程实现来发送设备的gps信息,我需要在父设备和子设备之间共享设备中的令牌。
我的问题是,不要分享那个对象而且孩子总是要求一个新的tokwn。而不是在它过期之前使用它。
我的令牌是这样的:
{"token":"f93cefe254ca873755b3bbbdca2f4c94","timeout":300,"expire":1512552810822}
当我在runChild中调试时,我总是为radioAccess获取不同的值,并且对于我需要的每个新令牌,我向设备发出新的请求......
我可以做些什么来坚持" radioAcess"全球对象?
nsGPSService.js
require('./globals');
var listRoutDirectories = getDirectories(routeDirectory);
for (var i = 0; i < listRoutDirectories.length; i++) {
var directoryName = listRoutDirectories[i];
var directoryPath = routeDirectory + '/' + listRoutDirectories[i];
var directoryFiles = getFiles(directoryPath);
for (var j = 0; j < directoryFiles.length; j++) {
var file = directoryFiles[j];
if (file.indexOf('Controller.js') > -1) {
global.Controllers[file.replace('Controller.js', '')] = require(directoryPath + '/' + file);
} else if (file.indexOf('Model.js') > -1) {
global.Models[file.replace('Model.js', '')] = require(directoryPath + '/' + file);
} else if (file.indexOf('Database.js') > -1) {
global.Database[file.replace('Database.js', '')] = require(directoryPath + '/' + file);
}
}
}
var child_process = require("child_process");
var argv = require('minimist')(process.argv.slice(2));
//ex: nsGPSService.js -d 1111-11-11-111
var deviceId = argv.d;
var processDevices = [];
function runParent () {
setTimeout(function() {
var numDevice = 1;
createLog('info', __dirname, __filename.slice(__dirname.length + 1, -3), null, 'runParent', "");
return Database.Devices.getDevices().then(function (devices) {
return new Promise(function (resolve, reject) {
async.each(devices, function (device, callback) {
var result = _.filter(processDevices, {"id": device.id});
if(result.length == 0) {
logger.info('WSController-Service', 'runParent', 'getRadioInfo --> ', device.id, ' :: ', numDevice++, '/', devices.length);
var process = child_process.fork(__dirname + '/nsGPSService.js', ["-d", device.id]);
processDevices.push({ "process": process, "id": device.id });
process.radioAccess = radioAccess[deviceId] || {};
createLog('debug', __dirname, __filename.slice(__dirname.length + 1, -3), device.id, 'runParent', 'process.radioAccess ', process.radioAccess);
process.on('message', function(data) {
//receber mensagens do filho
createLog('debug', __dirname, __filename.slice(__dirname.length + 1, -3), data.deviceId, 'runParent data', data);
if(data.reason == "deleted") {
//child acabou o processo e informa o parent para remover da lista
var index = _.findIndex(processDevices, {"id": data.deviceId});
processDevices.splice(index, 1);
}
});
process.on('exit', function(code) {
createLog('debug', __dirname, __filename.slice(__dirname.length + 1, -3), device.id, 'runParent', 'Exiting with code', code);
});
process.on("uncaughtException", function (error) {
createLog('error', __dirname, __filename.slice(__dirname.length + 1, -3), device.id, 'runParent', 'error', error);
process.exit(1);
});
}
callback();
}, function(error) {
// createLog('error', __dirname, __filename.slice(__dirname.length + 1, -3), null, 'runParent', 'error', error);
error ? reject(error) : resolve();
});
}).then(function() {
runParent()
}).catch(function(error) {
createLog('error', __dirname, __filename.slice(__dirname.length + 1, -3), null, 'runParent', 'catch error', error);
runParent()
});
});
},5000);
}
if(!deviceId) {
createLog('info', __dirname, __filename.slice(__dirname.length + 1, -3), deviceId, 'runParent');
runParent();
}
function runChild (id) {
createLog('info', __dirname, __filename.slice(__dirname.length + 1, -3), id, 'runChild', "");
setTimeout(function() {
return Database.Devices.getDeviceById(id).then(function(device) {
process.radioAccess = radioAccess[deviceId] || {};
createLog('debug', __dirname, __filename.slice(__dirname.length + 1, -3), device.id, 'runChild', 'process.radioAccess 1', process.radioAccess);
if(!device) {
process.exit();
return;
}
return Controllers.Gps.getRadioInfo('gps', 'info', {}, device).then(function (data) {
createLog('debug', __dirname, __filename.slice(__dirname.length + 1, - 3), id, 'runChild', 'data', data);
createLog('debug', __dirname, __filename.slice(__dirname.length + 1, -3), device.id, 'runChild', 'process.radioAccess 2', process.radioAccess);
return Controllers.Gps.sendDeviceInfo(data, device);
}).then(function() {
return runChild(id);
}).catch(function (e) {
createLog('error', __dirname, __filename.slice(__dirname.length + 1, - 3), id, 'runChild callback error', e);
return runChild(id);
});
});
}, 5000);
}
runChild(deviceId);
globals.js
global.radioAccess = {};
我尝试使用全局流程并添加&#34; process.radioAcess&#34;但是父母总是给{}而且孩子不能坚持代币。
答案 0 :(得分:0)
这是一个如何做到这一点的工作示例。请小心尝试在进程初始化之前从进程发送消息(例如在two.js中)和main.js中我在超时时退出进程以使two.js有机会向one.js发送内容
调试这个很难,我不知道为什么但是chrome调试器无法附加到子进程而且不会停在调试器语句中。子进程中的任何console.log语句也不会显示。
<强> main.js 强>
const fork = require('child_process').fork;
const path = require('path');
const[one,two] = ["one.js","two.js"]
.map(
fileName => [path.resolve(fileName),fileName]
)
.map(
([file,fileName]) => {
const x = fork(
file,
[],
{
stdio: [ 'pipe', 'pipe', 'pipe', 'ipc' ],
silent:false
}
);
x.stderr.on(//doesn't do anything
'error',
data =>
console.log(`got error from ${fileName}:`,data)
);
x.on(
'message',
message =>
(message.type==="relay")
? one.send({type:"ping",text:`relayed from ${fileName}: ${message.text}`})
: console.log(`got message from ${fileName}:`,message.text)
);
return x;
}
);
setTimeout(
_=>{
//do this after two can send relayd message (after the send on the que from two)
one.send({type:"ping",text:"hello one"})
one.send({type:"exit"})
two.send({type:"ping",text:"hello two"})
two.send({type:"exit"})
}
,100
);
<强> two.js 强>
//process is impossible to debug:
// debugger;//never breaks and about:inspect in chrome
// after init doesn't show this process either
// console.log("useless in forked process"); console.log doesn't show
const processMessage = message => {
switch (message.type) {
case "exit":
process.send({type:"string",text:"Going to exit."});
process.exit(0);
break;
case "ping":
process.send({type:"string",text:message.text});
break;
default:
process.send({type:"string",text:"unknown message"});
}
};
process.on(
'message',
message =>
processMessage(message)
);
//this part is not in one.js
Promise.resolve()
.then(
//send message after main had time to initialize all processes
x=>process.send({type:"relay",text:"HELLO THERE ONE"})
)
<强> one.js 强>
与two.js相同但没有最后一部分。