Electron系列文章-进程间通讯

进程之间通讯

在使用Electron开发应用的时候,咱们每每须要在主进程和渲染进程之间互相传递数据来实现产品的需求。json

假设咱们如今要作一个APP,APP中有一个窗口来显示当前机器的CPU型号,总内存等信息。逻辑很简单,只须要拿到相关信息后,展现在窗口中就好了。在Electron的渲染进程中,没有直接提供API去获取相关的信息,因此要借助主进程去获取信息后,传递到渲染进程显示。bash

要实现这样的功能,咱们能够用如下三种方式来实现electron

  • 方法调用
  • 数据共享
  • 数据消息

咱们来用代码例子来分别讲解下这三种方式ui

示例程序的主要目录结构以下spa

demo/
├── main
│   ├── systemInfo.js
│   └── index.js
├── package.json
└── renderer
    └── index.js
复制代码

方法调用

//主进程代码 main/systemInfo.js
var os = require('os');

//获取CPU信息
function getCpu(){
    var cores = os.cpus();
    if(cores.length > 0){
        return cores[0].model;
    }
}

exports.getCpu = getCpu;
复制代码
//渲染进程代码 renderer/index.js
//咱们须要在这里获取主进程才能获取的信息
const obj = require('electron').remote.require('./systemInfo')
const cpuInfo = obj.getCpu();
console.log(cpuInfo);
复制代码

在这个例子中,咱们经过Electron提供的remote模块去require一个主进程才能执行的模块,拿到须要的信息。这样咱们就能在渲染进程的窗口中,显示设备信息。接下来再看看数据共享怎么实现。设计

数据共享

上面的例子使用了remote.require去间接调用主进程方法实现,在数据共享中,不直接调用方法,而是直接从主进程拿到相关数据。code

//主进程代码 main/systemInfo.js
const os = require('os');

//获取CPU信息
function getCpu(){
    const cores = os.cpus();
    if(cores.length > 0){
        return cores[0].model;
    }
}

exports.getCpu = getCpu;
复制代码
//主进程代码 main/index.js
const getCpu = require('./systemInfo');
const cpuInfo = getCpu();
global['cpuInfo'] = cpuInfo;
复制代码
//渲染进程代码 renderer/index.js
const cpuInfo = require('electron').remote.getGlobal('cpuInfo');
复制代码

在这个例子中,咱们在主进程中先经过systemInfo模块获取信息,而后把信息存入Electron的全局对象global中。在渲染进程中,经过remote对象提供的getGlobal方法,能够直接获取到全局对象global中的属性值,实现咱们想要的功能。这个方案的缺点是,渲染进行想要的信息,要在获取以前先生成好并存入global对象的属性中,每次获取的都是固定的值。而对于上个例子而言,较为被动,由于上个例子至关因而主动获取,当值改变时,能够拿到最新的值。对象

上面的两种实现方法都是经过remote模块实现的,那remote模块究竟是什么呢?进程

remote模块是Electorn专门设计用来加强渲染进程能力的对象,他提供了诸如require、getGlobal等方法来获取主进程的一些信息。当经过remote去调用远程方法和共享变量时,其实是在发送相应的同步消息。关于消息,咱们先看下面的例子。事件

数据消息

一样,咱们要在渲染进程获取数据

//主进程代码 main/systemInfo.js
const os = require('os');

//获取CPU信息
function getCpu(){
    const cores = os.cpus();
    if(cores.length > 0){
        return cores[0].model;
    }
}

exports.getCpu = getCpu;
复制代码
//主进程代码 main/index.js
const getCpu = require('./systemInfo');
const ipc = require('electron').ipcMain;

ipc.on('get-cpu-info', function (event, arg) {
  event.sender.send('cpu-info-reply', getCpu())
})
复制代码
//渲染进程代码 renderer/index.js
const ipc = require('electron').ipcRenderer;
const getCpuInfoBtn = document.getElementById('info-btn');
getCpuInfoBtn.addEventListener('click', function () {
  ipc.send('get-cpu-info');
})

ipc.on('cpu-info-reply', function (event, arg) {
    console.log(arg);
})
复制代码

这里咱们没有使用remote模块,而是使用了Electron提供的IPC模块来实现需求。IPC模块是Electron提供的用于主进程与渲染进程通讯的模块,使用上跟事件的发布订阅相似,在消息的发起方经过ipc模块send事件,同时在接收方监听对应事件。在第二个例子中的结尾,说到的remote的调用其实是在发送同步消息,也是利用了ipc的sync消息一样的原理来实现的。

在这个需求中,是渲染进程须要向主进程拿信息。有些场景下,多是主进程要主动向渲染进程拿消息,实现方式相似,只须要更换下主次。

总结

主进程与渲染进程间通讯所涉及的两大模块

  • remote:能经过方法直接调用以及全局变量获取来实现数据的传递
  • ipc:能经过事件注册发布的方式实现数据传递
相关文章
相关标签/搜索