我正在使用 Electron (io.js + Chrome) 开发单页应用程序。此应用程序接口(interface)的 SDK 需要轮询/心跳来运行其主/事件循环(类似于 libusb 及其 libusb_handle_events_timeout_completed API)。我希望使用 Worker 线程和计时器,但似乎沙箱可能使此选项变得不可能 - 除非我错过了一些东西。我已经在工作线程中测试了计时器功能,效果很好。但是,我需要 require
各种其他模块(ffi 等)才能与 SDK 进行通信;但是,require
不适用于 Worker
线程。
是否有任何其他选项/API/模块/等可用,可以让我启动一个可以需要
其他模块的新线程,这样我就可以每隔几毫秒对这个 SDK 进行一次简单的调用?只要我对主线程有一些 IPC,这个新线程就可以成为该 SDK 的唯一通信者,因此应该不会出现损坏问题。任何建议或进一步的研究领域将不胜感激。
最佳答案
在花了更多时间解决这个问题之后,我发现 Node.js 集群对我来说是最好的方法。我有能力:
需要
任何代码。- 仍然有一个漂亮整洁的 IPC。
- 可以监控 fork 集群(进程)的生命周期。
我确实学到了一件事。我还学到了一些东西:
- 如果你像我一样使用 Electron,请确保使用 cluster.setupMaster() ,否则当集群 fork 时,它将尝试使用 Electron 环境,这会抛出一堆
bad option
错误,cluster.fork
将失败。 - 我发现的另一个问题是,如果您的应用没有终端并且您在工作集群中使用
console.log
,集群将会终止。我不确定这是否仅特定于 Electron (io.js) 还是什么,但这需要一些时间才能弄清楚。该应用程序运行,并且可以通过终端很好地记录日志。如果没有终端,它就会终止工作人员。由于我的工作程序的第一行是console.log
,因此更难找到。
可能有更好的解决方案,但这似乎最适合我的用例。
对于那些感兴趣的人来说,简化的实现看起来像这样:
app.js
var cluster = require('cluster');
var path = require('path');
var sdkWorker = null;
// MUST use the setupMaster otherwise the default electron
// environment is used and will fail with:
// ../node_modules/electron-prebuilt/dist/electron: bad option: --type=renderer
// ...
cluster.setupMaster({
exec: path.join(__dirname, "sdk_worker.js"),
//args: ['--use', 'https'],
silent: false
});
sdkWorker = cluster.fork({});
cluster.on('fork', function(worker) {
console.log('WORKER: forked: ' + worker.process.pid);
});
cluster.on('online', function(worker) {
console.log('WORKER: ' + worker.process.pid + ' is online');
});
cluster.on('exit', function(worker, code, signal) {
var suicide = "";
if (worker.suicide === true) {
suicide = " [SUICIDE] ";
}
console.log('EXIT: WORKER: '+suicide+ worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal);
sdkWorker = null;
//console.log('Starting a new worker');
//this.sdkWorker = cluster.fork();
});
sdkWorker.on( 'message', function( msg ) {
console.log("FROM SDK: "+msg.cmdId);
} );
// Init the lib and SDK platform
sdkWorker.send( {cmdId:"init"} );
// Do an initial enumeration of USB
sdkWorker.send( {cmdId:"enumUsb"} );
// Start the contant polling of the SDK
sdkWorker.send( {cmdId:"startPoll"} );
sdk_worker.js
// Cluster support
process.on('message', function(msg) {
//console.log("FROM MASTER: "+msg.cmdId); //////// BAD
});
关于Javascript工作线程选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32855929/