在流程nodejs

时间:2017-12-06 09:36:47

标签: javascript node.js

我遇到了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;但是父母总是给{}而且孩子不能坚持代币。

1 个答案:

答案 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相同但没有最后一部分。