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:能經過事件註冊發佈的方式實現數據傳遞
相關文章
相關標籤/搜索